You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDFBox从1.8.8升级到2.0.26后打印PDF出现U+0000编码异常求助

PDFBox升级后打印PDF出现U+0000编码异常问题

将PDFBox从1.8.8版本升级到2.0.26后,部分场景下打印PDF会抛出异常,已尝试更换fontbox/pdfbox版本但未解决。1.8.8版本无此问题,推测是U+0000空字符导致的编码兼容问题。

异常堆栈

Exception type: class javax.ejb.EJBException
Exception message: javax.servlet.ServletException: See nested exception; nested exception is: java.lang.IllegalArgumentException: U+0000 is not available in this font's encoding: WinAnsiEncoding
User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Stack trace:
javax.servlet.ServletException: See nested exception; nested exception is: java.lang.IllegalArgumentException: U+0000 is not available in this font's encoding: WinAnsiEncoding
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1290)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:778)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:475)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:152)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:94)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:111)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
    at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1021)
    at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1143)
    at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:82)
    at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:956)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:280)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:967)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:359)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:318)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:471)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:405)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:285)
    at com.ibm.ws.http.channel.internal.inbound.HttpICLReadCallback.complete(HttpICLReadCallback.java:66)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:929)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1018)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

相关代码

页脚文本添加代码

private static void addFooterText(PDPageContentStream contentStream, PdfProperties.AwFuer gesellschaftVon, PdfProperties.AwFuer gesellschaftFuer, PdfDocType docType) throws IOException {
    PDFont font = PDType1Font.HELVETICA;
    contentStream.beginText();
    contentStream.setFont(font, 6);
    contentStream.newLineAtOffset(225, 24);
    String docTypeKsu = getKsuDocType(docType);
    if (!TextConstants.AUDI_BESTELLUNG.equals(docTypeKsu)) {
        String gkzFuer = gesellschaftFuer.getGesellschaftFuer();
        String gkzVon = gesellschaftVon.getGesellschaftFuer();
        String ksuString = KsuTextFrontEnd.getKsuText(docTypeKsu, gkzVon, gkzFuer); // CR819
        contentStream.showText(ksuString); // CR819
    }
}

private static void addFooterTextFinal(PDPageContentStream contentStream, PdfProperties.AwFuer gesellschaftVon, PdfProperties.AwFuer gesellschaftFuer, PdfDocType docType) throws IOException {
    PDFont font = PDType1Font.HELVETICA;
    contentStream.beginText();
    contentStream.setFont(font, 6);
    contentStream.newLineAtOffset(225, 24);
    String docTypeKsu = getKsuDocType(docType);
    String gkzFuer = gesellschaftFuer.getGesellschaftFuer();
    String gkzVon = gesellschaftVon.getGesellschaftFuer();
    String ksuString = KsuTextFrontEnd.getKsuText(docTypeKsu, gkzVon, gkzFuer);
    contentStream.showText(ksuString);
}

PDF创建代码

public void create(Map hashmap, OutputStream out, String FormularName)
throws PdfException {

    PDDocument pdf = null;
    try {
        pdf = PDDocument.load(new File(FormularName));

        PDDocumentCatalog docCatalog = pdf.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();

        List<?> fields = acroForm.getFields();
        Iterator<?> fieldsIter = fields.iterator();

        while (fieldsIter.hasNext()) {
            PDField field = (PDField) fieldsIter.next();
            String value = field.getPartialName().toString();
            if (hashmap.containsKey(value)) {
                field.setValue((String) hashmap.get(value));
            } else {
                continue;
            }
        }

        try {
            pdf.save(out);
        } catch (IOException e) {
            LOGGER.error(e);
            throw new PdfException(e.getMessage());
        }
    } catch (IOException e2) {
        LOGGER.error(e2);
        throw new PdfException(e2.getMessage());
    } finally {
        if (pdf != null) {
            try {
                pdf.close();
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    }
}

问题分析与解决方法

原因

PDFBox 2.x版本对字符编码的校验比1.8.x更严格,U+0000(空字符)不属于WinAnsiEncoding的支持范围,当调用showText传入包含该字符的字符串时会直接抛出异常;而1.8.x版本可能自动忽略了这类非法字符,因此无报错。

解决方法

  1. 过滤非法字符:在调用showText前,对字符串中的U+0000进行替换或移除,示例:
ksuString = ksuString.replace("\u0000", "");
// 或者移除所有控制字符(可选)
ksuString = ksuString.replaceAll("\\p{Cntrl}", "");
  1. 检查数据源:排查gesellschaftFuer.getGesellschaftFuer()、gesellschaftVon.getGesellschaftFuer()以及KsuTextFrontEnd.getKsuText的返回值,确保源头数据不包含空字符。
  2. 字体编码适配:如果业务需要保留特殊字符,可以尝试使用支持Unicode编码的字体(如PDType0Font加载TrueType字体),但此方法复杂度较高,优先推荐前两种方案。

内容的提问来源于stack exchange,提问作者Vieckov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:30:29