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

IText 5.5.11解析HTML元素:cp1250编码与三列布局配置求助

解决iText 5.5.11解析含中欧特殊字符的HTML为三列PDF的问题

我来帮你搞定这个难题——既要处理č、ž、ř这类中欧特殊字符的编码乱码问题,还要实现三列布局,同时还不能修改原HTML字符串对吧?下面是针对性的解决方案:

1. 解析时明确指定CP1250编码

iText 5的XMLWorker默认会用UTF-8解析HTML,如果你原HTML是CP1250编码的,必须在解析阶段明确指定编码,否则特殊字符肯定会乱码。

如果你用parseElementList方法,直接传入编码参数即可:

// 假设html是你要解析的CP1250编码字符串
ElementList elements = XMLWorkerHelper.parseElementList(html, "cp1250");

要是用parseXHtml结合写入器,得同时指定输入流的编码和字符集:

ByteArrayInputStream inputStream = new ByteArrayInputStream(html.getBytes("cp1250"));
XMLWorkerHelper.getInstance().parseXHtml(writer, document, inputStream, Charset.forName("cp1250"));

2. 注册支持中欧字符的字体

光设置编码还不够,你得确保PDF用的字体能识别č、ž、ř这些字符——默认的Helvetica字体不包含中欧字符,这也是很多人忽略的乱码原因。

你可以注册本地支持CP1250的字体(比如Windows系统里的ArialCE.ttf,或者开源的LiberationSans系列字体),然后在解析时指定字体提供者:

// 注册字体,替换成你本地字体的实际路径
FontFactory.register("C:/Windows/Fonts/arialce.ttf", "ArialCE");

// 创建自定义字体提供者,避免默认字体查找逻辑
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("C:/Windows/Fonts/arialce.ttf");

// 解析时同时传入编码和字体提供者
ElementList elements = XMLWorkerHelper.parseElementList(
    html, 
    "cp1250", 
    fontProvider
);

3. 用ColumnText实现三列布局

解析得到元素列表后,你可以用iText的ColumnText类把元素分配到三列中绘制,完美实现三列布局:

Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("three-column.pdf"));
document.open();

// 先按前面的方法解析得到元素列表
ElementList elements = XMLWorkerHelper.parseElementList(html, "cp1250", fontProvider);

// 计算三列的尺寸和位置
float pageWidth = document.getPageSize().getWidth();
float marginLeft = document.leftMargin();
float marginRight = document.rightMargin();
float marginTop = document.topMargin();
float marginBottom = document.bottomMargin();

float columnWidth = (pageWidth - marginLeft - marginRight) / 3;
// 三列的起始X坐标
float[] columnXs = {
    marginLeft,
    marginLeft + columnWidth,
    marginLeft + 2 * columnWidth
};
float columnYTop = document.getPageSize().getHeight() - marginTop;
float columnYBottom = marginBottom;

ColumnText columnText = new ColumnText(writer.getDirectContent());
int elemIndex = 0;

// 遍历每一列,填充元素
for (float x : columnXs) {
    columnText.setSimpleColumn(
        x, 
        columnYBottom, 
        x + columnWidth, 
        columnYTop
    );
    
    // 往当前列添加元素,直到列满或元素用完
    while (elemIndex < elements.size()) {
        int status = columnText.addElement(elements.get(elemIndex));
        if (ColumnText.hasMoreText(status)) {
            // 当前列已满,切换到下一列
            break;
        }
        elemIndex++;
    }
    columnText.go();
    // 重置ColumnText状态,准备下一列
    columnText.setText(null);
}

document.close();

关键注意点

  • 先确认原HTML的编码确实是CP1250,可以用Notepad++这类工具查看编码格式,避免编码不匹配的问题。
  • 字体文件要确保可访问,打包项目时记得把字体文件一起打包,或者使用内嵌字体(添加BaseFont.EMBEDDED参数),避免在其他机器上显示异常。

内容的提问来源于stack exchange,提问作者Martin Závodný

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:15:23