When generating PDF documents from HTML in Java applications, incorrect character encoding can cause Chinese text to appear as garbled characters. The primary cause is the PDF library failing to recognize and apply the correct font set and encoding for the HTML content.
Solution: Configure Font Provider and Encoding
To ensure correct rendering of Chinese characters, you must explicitly define a font that contains the necessary glyphs and set the proper character encoding. Using iText with the XML Worker, the key is to create and register an FontProvider.
| Step | Action |
|---|---|
| 1 | Import required librarries. |
| 2 | Prepare HTML content with UTF-8 charset. |
| 3 | Configure a custom font provider with a Chinese-capable font. |
| 4 | Generate the PDF using the configured parser. |
Implementation Steps
-
Import Dependencies Ensure your project includes the necessary iText libraries (e.g.,
itextpdf,xmlworker). -
Prepare HTML with Correct Encoding The HTML source must explicitly declare UTF-8 encoding in its
<head>section.String htmlData = "<html><head><meta charset='UTF-8'></head><body><h1>测试文档</h1><p>这是一段中文内容。</p></body></html>"; -
Configure Fonts for the PDF Worker Create a font provider that points to a TrueType font (.ttf) file that supports Chinese characters. The font file must be accessible to your application.
import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.itextpdf.tool.xml.XMLWorkerHelper; import com.itextpdf.tool.xml.css.StyleAttrCSSResolver; import com.itextpdf.tool.xml.pipeline.css.CSSResolver; import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline; import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline; import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; import java.io.*; public class HtmlToPdfConverter { public void convertHtmlToPdf(String html, String pdfOutputPath) throws Exception { Document pdfDoc = new Document(); PdfWriter pdfWriter = PdfWriter.getInstance(pdfDoc, new FileOutputStream(pdfOutputPath)); pdfDoc.open(); // Create a font provider and register a Chinese font XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontProvider.register("./fonts/simsun.ttf"); // Path to your Chinese font file CSSResolver cssResolver = new StyleAttrCSSResolver(); HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); htmlContext.setFontProvider(fontProvider); // Set the custom font provider PdfWriterPipeline pdfPipeline = new PdfWriterPipeline(pdfDoc, pdfWriter); HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, pdfPipeline); XMLWorkerHelper worker = XMLWorkerHelper.getInstance(); // Parse the HTML input stream try (InputStream htmlStream = new ByteArrayInputStream(html.getBytes("UTF-8"))) { worker.parseXHtml(pdfWriter, pdfDoc, htmlStream, null, Charset.forName("UTF-8"), fontProvider); } pdfDoc.close(); } } -
Generate the PDF Execute the conversion method with your HTML string and output file path.
HtmlToPdfConverter converter = new HtmlToPdfConverter(); converter.convertHtmlToPdf(htmlData, "./output/report.pdf");
Critical Points for Success
- Font File: The specified
.ttffont file must reliably support the Chinese characters used in your document. Commmon system fonts like SimSun or a freely licensed font like Noto Sans CJK can be used. - Encoding Consistency: Use
UTF-8encoding consistently: in the HTML<meta>tag, when converting the HTML string to a byte array (getBytes("UTF-8")), and when configuring the XML worker. - Library Version: Be aware that API details may differ between majer versions of iText and XML Worker. The above example is based on older, commonly used versions (e.g., iText 5). For newer iText 7, the approach involves using the
pdfHTMLadd-on with converter properties.