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

使用Java中iText XMLWorker为何出现奇怪错误?

解决XMLWorkerHelper解析HTML时的NumberFormatException("100%"输入字符串)

问题原因

XMLWorker(iText 5配套的HTML解析组件)对CSS属性的百分比单位支持存在缺陷,当解析类似width:100%这类样式时,会错误地尝试将带百分号的字符串直接转换为纯数字,从而抛出NumberFormatException。

解决方案

方案1:迁移至pdfHTML(官方推荐)

XMLWorker已被官方弃用,iText 7的pdfHTML组件对CSS和HTML的支持更完善,原生支持百分比单位。迁移步骤如下:

  • 引入依赖(Maven示例):
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>5.0.0</version> <!-- 建议使用最新稳定版 -->
</dependency>
  • 重写转换函数:
byte[] convertHtmlToPdfBytes(String htmlString) throws IOException {
    ByteArrayOutputStream outp = new ByteArrayOutputStream();
    HtmlConverter.convertToPdf(htmlString, outp);
    return outp.toByteArray();
}

方案2:自定义CSS解析器(兼容iText 5场景)

如果无法升级到iText 7,可以通过自定义CSS解析逻辑处理百分比:

  • 实现自定义CSS解析器:
public class CustomCssResolver extends StyleAttrCSSResolver {
    @Override
    public void resolveStyles(Tag tag) {
        super.resolveStyles(tag);
        Map<String, String> styles = tag.getCSS();
        
        // 处理width属性的百分比
        if (styles.containsKey("width")) {
            String widthVal = styles.get("width");
            if (widthVal.endsWith("%")) {
                // 计算对应页面宽度的具体数值(以A4默认页面为例)
                float pageWidth = Document.getDefaultPageSize().getWidth();
                float percent = Float.parseFloat(widthVal.replace("%", "")) / 100;
                styles.put("width", String.valueOf(pageWidth * percent));
            }
        }
        
        // 可按需添加其他百分比属性的处理,比如height、padding等
    }
}
  • 修改原函数使用自定义解析器:
byte[] convertHtmlToPdfBytes(String htmlString) throws IOException, DocumentException {
    Document document = new Document();
    ByteArrayOutputStream outp = new ByteArrayOutputStream();
    PdfWriter writer = PdfWriter.getInstance(document, outp);
    document.open();

    InputStream inp = IOUtils.toInputStream(htmlString);
    
    // 构建自定义XMLWorker处理链
    CustomCssResolver cssResolver = new CustomCssResolver();
    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    
    PdfWriterPipeline pdfPipeline = new PdfWriterPipeline(document, writer);
    HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, pdfPipeline);
    CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    
    XMLWorker worker = new XMLWorker(cssPipeline, true);
    XMLParser parser = new XMLParser(worker);
    parser.parse(inp);

    document.close();
    return outp.toByteArray();
}

方案3:修改HTML中的样式写法(内容可控时使用)

如果HTML内容由你控制,可以将引发错误的百分比样式替换为XMLWorker兼容的格式,比如将width:100%替换为具体的页面宽度数值(A4页面默认宽度为595pt,即width:595pt)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:53:01