xml to pdf 完美支持中文字符

本文介绍如何修改iTextXMLWorker源码以完美支持HTML中文字符转换为PDF,包括源码修改细节及转换效果对比。

micmiu – 软件开发+生活点滴

 

iText XML Worker修改源码完美支持HTML中文字符转PDF

作者: Michael 日期: 2012 年 11 月 26 日发表评论 (54)查看评论

目录:

  1. 介绍
  2. 中文字符转换
  3. 转换效果

[一]、介绍

XML Worker是辅助iText用于把XML、XHTML转换PDF的一个开源的软件工具库,详细介绍可以参见下面的链接:

[二]、中文字符问题

如果HTML文件中包含中文字符,在转换成PDF是会无法显示,简单看了下它的源码,发现XML Worker无法设置默认字体,只好修改它的部分源码实现中文字符的转换。

附件提供修改后的lib包下载:xmlworker-1.2.1-micmiu.jar.zip  (源码:https://github.com/micmiu/micmiu-xmlworker

修改:com.itextpdf.tool.xml.css.apply.ChunkCssApplier.java 中的 public Chunk apply(final Chunk c, final Tag t)  这个方法,增加如下逻辑判断:

 

1

2

3

4

5

6

7

8

Font f = applyFontStyles(t);

// for chinese charater display @www.micmiu.com

if (null != HTMLUtils.bfCN && HTMLUtils.isChinese(c.getContent())) {

f = new Font(HTMLUtils.bfCN, f.getSize(), f.getStyle(),

f.getColor());

}

float size = f.getSize();

......

在:com.itextpdf.tool.xml.html.HTMLUtils.java 中 增加下面用于中文字符判断的方法:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

public static BaseFont bfCN = null;

static {

try {

bfCN = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H",

BaseFont.NOT_EMBEDDED);

} catch (Exception e) {

}

}

 

// add by Michael more see:http://www.micmiu.com

private static final boolean isChinese(char c) {

Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS

|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS

|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A

|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION

|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION

|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {

return true;

}

return false;

}

// add by Michael more see:http://www.micmiu.com

public static final boolean isChinese(String strName) {

char[] ch = strName.toCharArray();

for (int i = 0; i < ch.length; i++) {

char c = ch[i];

if (isChinese(c)) {

return true;

}

}

return false;

}

[三]、转换效果

演示一个简单的HTML文件:demo-cn.html

 

1

2

3

4

5

6

7

8

9

10

11

12

13

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="zh-CN">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>iText xmlworker</title>

</head>

<body>

<div>

<p>[ Hello iText English ]</p>

<p>[ 你好 iText 这是中文 ]</p>

</div>

</body>

</html>

转PDF的程序:   Demo4HTMLCn.java

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

package com.micmiu.pdf.itext;

 

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStreamReader;

 

import com.itextpdf.text.Document;

import com.itextpdf.text.pdf.PdfWriter;

import com.itextpdf.tool.xml.XMLWorkerHelper;

 

/**

* 测试xml worker 页面包含中文字符的转换

*

* @author <a href="http://www.micmiu.com">Michael Sun</a>

*/

public class Demo4HTMLCn {

 

/**

* @param args

*/

public static void main(String[] args) throws Exception {

String pdfFile = "d:/test/itext/demo-htmlcn.pdf";

String htmlFile = "d:/test/itext/demo-cn.html";

 

Document document = new Document();

PdfWriter pdfwriter = PdfWriter.getInstance(document,

new FileOutputStream(pdfFile));

pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);

document.open();

 

// html文件

InputStreamReader isr = new InputStreamReader(new FileInputStream(

htmlFile), "UTF-8");

XMLWorkerHelper.getInstance().parseXHtml(pdfwriter, document, isr);

document.close();

 

}

 

}

HTML页面、修改源码前 、修改源码后的效果对比图如下:

从上图可知,修改源码后,基本实现了对HTML的中文字符的支持。

本文介绍到此结束@Michael Sun.

原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴http://www.micmiu.com/ ]

本文链接地址: http://www.micmiu.com/opensource/expdoc/itext-xml-worker-cn/

 

MARK: 通过此博客将 xmlworker-5.5.6改造与 itextpdf-5.5.6完美配合,解决了以下异常

java.lang.NoSuchMethodError: com.itextpdf.text.pdf.PdfPTable.addCell(Lcom/itextpdf/text/pdf/PdfPCell;)V
<think>我们正在寻找将HTML文件转换为PDF的Java库。根据引用内容,我们可以总结出三个主要选项:htmltopdf-java(基于wkhtmltopdf)、iText7+pdfHTML(纯Java)和PDFreactor(商业级)。下面将分别介绍这三个库的使用方法、特点和适用场景。###1.htmltopdf-java(开源首选)[^1]这个库是基于wkhtmltopdf引擎的Java封装,因此它能够提供接近浏览器渲染的效果,支持复杂的CSS和JavaScript。**Maven依赖**:```xml<dependency><groupId>io.woo</groupId><artifactId>htmltopdf</artifactId><version>1.0.6</version></dependency>```**示例代码**:```javaimportio.woo.htmltopdf.HtmlToPdf;importio.woo.htmltopdf.HtmlToPdfObject;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassHtmlToPdfConverter{publicstaticvoidconvert(StringhtmlFilePath,StringpdfOutputPath)throwsException{//转换并获取PDF字节数组byte[]pdfBytes=HtmlToPdf.create().object(HtmlToPdfObject.forUrl("file:///"+htmlFilePath))//使用file:///协议指定本地文件.convert();//将字节数组写入文件Files.write(Paths.get(pdfOutputPath),pdfBytes);}publicstaticvoidmain(String[]args){try{convert("input.html","output.pdf");System.out.println("转换完成!");}catch(Exceptione){e.printStackTrace();}}}```**注意**:-使用前需要安装wkhtmltopdf,并确保其可执行文件在系统的PATH环境变量中。-支持Windows、Linux和macOS,需要从wkhtmltopdf官网下载对应的版本安装。**优点**:-开源免费(MIT许可证)-渲染质量高**缺点**:-需要额外安装wkhtmltopdf###2.iText7+pdfHTML(纯Java方案)[^3]iText是一个成熟的PDF处理库,其pdfHTML插件可以方便地将HTML转换为PDF,完全在Java环境中运行,无需外部依赖。**Maven依赖**:```xml<dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>4.0.4</version></dependency>```**示例代码**:```javaimportcom.itextpdf.html2pdf.HtmlConverter;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;publicclassHtmlToPdfConverter{publicstaticvoidconvert(StringhtmlFilePath,StringpdfOutputPath)throwsIOException{try(FileOutputStreamoutputStream=newFileOutputStream(pdfOutputPath)){HtmlConverter.convertToPdf(newFile(htmlFilePath),outputStream);}}publicstaticvoidmain(String[]args){try{convert("input.html","output.pdf");System.out.println("转换完成!");}catch(IOExceptione){e.printStackTrace();}}}```**注意**:-iText7的pdfHTML插件在AGPL许可证下发布,如果用于商业项目且不想开源自己的代码,需要购买商业许可证。**优点**:-纯Java实现,无外部依赖-部署简单**缺点**:-对复杂CSS和JavaScript的支持不如wkhtmltopdf-商业使用需注意许可证问题###3.PDFreactor(企业级方案)[^2]PDFreactor是一款商业级HTML转PDF工具,提供高质量的渲染效果和丰富的功能,支持多种编程语言集成。**使用步骤**:1.从PDFreactor官网获取试用版或购买许可证。2.下载PDFreactor的Java客户端库。3.按照文档进行集成。**示例代码**:```javaimportcom.realobjects.pdfreactor.PDFreactor;importjava.io.File;importjava.nio.file.Files;publicclassHtmlToPdfConverter{publicstaticvoidconvert(StringhtmlFilePath,StringpdfOutputPath)throwsException{PDFreactorpdfReactor=newPDFreactor();//设置授权密钥(如果有)//pdfReactor.setLicenseKey("...");//将HTML文件转换为PDFStringresult=pdfReactor.renderDocumentFromURL("file:///"+newFile(htmlFilePath).getAbsolutePath());Files.write(newFile(pdfOutputPath).toPath(),result.getBytes());}publicstaticvoidmain(String[]args){try{convert("input.html","output.pdf");System.out.println("转换完成!");}catch(Exceptione){e.printStackTrace();}}}```**优点**:-渲染质量非常高,支持最新的CSS和JavaScript-提供丰富的API和配置选项**缺点**:-商业软件,需要付费###总结-**开源免费**:推荐htmltopdf-java,但需要安装wkhtmltopdf。-**纯Java无依赖**:推荐iText7,注意AGPL许可证。-**企业级需求**:推荐PDFreactor,但需要购买许可证。###中文乱码解决方案在HTML文件中确保指定了正确的字符集(如UTF-8)并设置中文字体:```html<!DOCTYPEhtml><html><head><metacharset="UTF-8"><style>body{font-family:"SimSun","MicrosoftYaHei",sans-serif;}</style></head><body><!--内容--></body></html>```§§相关问题§§1.如何解决wkhtmltopdf在Linux服务器上的安装和配置问题?[^1][^3]2.使用iText7转换HTML到PDF时,如何调整页面大小和缩放比例?[^3]3.在商业项目中使用iText7需要注意哪些许可证问题?4.PDFreactor与其他商业HTML转PDF工具相比有哪些优势?[^2]</think>### Java实现HTML转PDF的推荐库及方案 根据引用内容,以下是三种经过验证的解决方案,按优先级排序: --- #### 1. **htmltopdf-java(开源首选)[^1]** ```java // Maven依赖 <dependency> <groupId>io.woo</groupId> <artifactId>htmltopdf</artifactId> <version>1.0.6</version> </dependency> // 转换示例 import io.woo.htmltopdf.HtmlToPdf; import io.woo.htmltopdf.HtmlToPdfObject; public class HtmlToPdfConverter { public static void convert(String htmlPath, String pdfPath) { try { byte[] pdfBytes = HtmlToPdf.create() .object(HtmlToPdfObject.forUrl("file://" + htmlPath)) .convert(); Files.write(Paths.get(pdfPath), pdfBytes); } catch (Exception e) { e.printStackTrace(); } } } ``` **特点**: - 基于成熟的`wkhtmltopdf`引擎,完美支持CSS3/JavaScript - 开源免费(MIT许可证) - 渲染效果接近浏览器输出 **注意**:需安装`wkhtmltopdf`并配置环境变量([安装指南](https://wkhtmltopdf.org/)) --- #### 2. **iText 7 + pdfHTML(纯Java方案)[^3]** ```java // Maven依赖 <dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>4.0.4</version> </dependency> // 转换示例 import com.itextpdf.html2pdf.HtmlConverter; public class HtmlToPdfConverter { public static void convert(String htmlPath, String pdfPath) { try { HtmlConverter.convertToPdf( new FileInputStream(htmlPath), new FileOutputStream(pdfPath) ); } catch (Exception e) { e.printStackTrace(); } } } ``` **特点**: - 纯Java实现,无外部依赖 - 支持动态内容缩放和页面大小调整 - AGPL许可证(商业使用需授权) --- #### 3. **PDFreactor(企业级方案)[^2]** ```java // 官方示例(需商业授权) import com.realobjects.pdfreactor.*; public class HtmlToPdfConverter { public static void convert(String htmlUrl, String pdfPath) { try { PDFreactor pdfReactor = new PDFreactor(); byte[] pdfBytes = pdfReactor.renderDocumentAsBinary( htmlUrl, new Configuration().setViewportWidth(1200) ); Files.write(Paths.get(pdfPath), pdfBytes); } catch (Exception e) { e.printStackTrace(); } } } ``` **特点**: - 企业级渲染质量(支持复杂CSS/JS) - 提供REST API和多种语言SDK - 商业付费方案(提供免费试用) --- ### 中文支持方案 在HTML中添加: ```html <meta charset="UTF-8"> <style> body { font-family: "SimSun", "Microsoft YaHei", sans-serif; } </style> ``` 在代码中指定字体: ```java // iText示例 ConverterProperties props = new ConverterProperties(); FontProvider fontProvider = new DefaultFontProvider(); fontProvider.addFont("fonts/simsun.ttf"); // 添加本地字体 props.setFontProvider(fontProvider); HtmlConverter.convertToPdf(htmlSource, pdfDest, props); ``` --- ### 性能对比 | 指标 | htmltopdf-java | iText 7 | PDFreactor | |---------------------|----------------------|----------------------|---------------------| | **渲染质量** | ★★★★☆ | ★★★☆☆ | ★★★★★ | | **JS支持** | 完整 | 部分 | 完整 | | **部署复杂度** | 需外部二进制 | 纯Java | JAR依赖 | | **成本** | 免费 | AGPL/商业授权 | 商业授权 | --- ### 选择建议 1. **优先考虑开源**:选`htmltopdf-java`(需接受外部依赖) 2. **要求纯Java**:选`iText 7`(注意许可证) 3. **企业级需求**:选`PDFreactor`(预算充足时) > **测试建议**:先用简单HTML测试核心功能,再逐步添加复杂样式 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值