如何在iText生成的PDF中添加SVG?渲染异常及内容丢失问题求助
解决HTML转PDF后添加SVG图片的问题
问题分析
- 直接用
ITextRenderer转换HTML时,SVG无法正确渲染,原因是该组件对SVG的支持不完善,导致SVG内容显示为乱码文本 - 单独使用
SvgConverter会丢失原有HTML内容,因为没有处理HTML到PDF的转换流程
最优解决方案(iText 7新API)
使用iText 7官方的HtmlConverter处理HTML转PDF,再用SvgConverter在末尾添加SVG图片,两者同属一个技术体系,兼容性和可靠性更强。
示例代码
import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.WriterProperties; import com.itextpdf.svg.converter.SvgConverter; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class HtmlPdfWithSvg { public static void main(String[] args) throws IOException { // 路径注意:Windows系统下反斜杠需转义为\\,或使用正斜杠/ File htmlFile = new File("D:\\testowy.txt"); File svgFile = new File("D:\\chart.svg"); // JFreeChart生成的SVG文件 File outputPdf = new File("D:\\testww.pdf"); // 初始化PDF写入器和文档 PdfWriter writer = new PdfWriter(new FileOutputStream(outputPdf), new WriterProperties().setCompressionLevel(0)); PdfDocument pdfDoc = new PdfDocument(writer); // 1. 将HTML内容渲染到PDF中 HtmlConverter.convertToDocument(IOUtils.readFileToString(htmlFile, "UTF-8"), pdfDoc); // 2. 添加新页面并绘制SVG pdfDoc.addNewPage(); int lastPage = pdfDoc.getNumberOfPages(); // 若SVG是JFreeChart生成的字符串,直接传入字符串即可,无需读取文件 SvgConverter.drawOnDocument(IOUtils.readFileToString(svgFile, "UTF-8"), pdfDoc, lastPage); // 关闭文档 pdfDoc.close(); } }
关键说明
HtmlConverter是iText 7专门的HTML转PDF工具,对现代HTML特性支持更完善,替代旧的ITextRenderer可避免SVG渲染问题- 先完成HTML转PDF流程,再添加新页面放置SVG,确保原有内容完整保留
- 如果SVG是JFreeChart直接生成的字符串(而非文件),直接把字符串传入
SvgConverter.drawOnDocument即可
兼容旧代码方案(保留ITextRenderer)
若必须使用ITextRenderer,可先生成HTML转PDF的临时文件,再合并SVG页面:
import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.WriterProperties; import com.itextpdf.svg.converter.SvgConverter; import org.apache.commons.io.IOUtils; import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class LegacyHtmlPdfWithSvg { public static void main(String[] args) throws IOException { File htmlFile = new File("D:\\testowy.txt"); File svgFile = new File("D:\\chart.svg"); File outputPdf = new File("D:\\testww.pdf"); File tempPdf = new File("D:\\temp_html.pdf"); // 第一步:用ITextRenderer生成HTML转PDF的临时文件 ITextRenderer renderer = new ITextRenderer(); renderer.setDocumentFromString(IOUtils.readFileToString(htmlFile, "UTF-8")); renderer.layout(); renderer.createPDF(new FileOutputStream(tempPdf)); renderer.finishPDF(); // 第二步:合并临时PDF并添加SVG页面 PdfWriter writer = new PdfWriter(new FileOutputStream(outputPdf), new WriterProperties().setCompressionLevel(0)); PdfDocument finalPdf = new PdfDocument(writer); PdfDocument tempDoc = new PdfDocument(new PdfReader(tempPdf)); // 复制临时PDF内容到最终文档 tempDoc.copyPagesTo(1, tempDoc.getNumberOfPages(), finalPdf); // 添加SVG页面 finalPdf.addNewPage(); int lastPage = finalPdf.getNumberOfPages(); SvgConverter.drawOnDocument(IOUtils.readFileToString(svgFile, "UTF-8"), finalPdf, lastPage); // 关闭文档并清理临时文件 tempDoc.close(); finalPdf.close(); tempPdf.delete(); } }
内容的提问来源于stack exchange,提问作者crosbee
相关产品推荐
相关产品推荐

