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

如何用iText高效处理大体积HTML转PDF(2MB/6-7MB场景)

iText HTML转PDF性能优化方案(针对大文件场景)

通用性能优化措施

  • 精简ConverterProperties配置
    • 关闭不必要的自动功能:禁用自动字体探测(若HTML使用已知字体),设置converterProperties.setFontProvider(new DefaultFontProvider(false, false, false))减少字体扫描开销;指定媒体类型为打印converterProperties.setMediaDeviceDescription(new MediaDeviceDescription(MediaType.PRINT)),避免多余的媒体适配逻辑。
    • 明确字符集:设置converterProperties.setCharset(StandardCharsets.UTF_8.name()),省去编码自动探测的耗时。
  • 优化IO操作
    • 使用带缓冲区的流:替换直接的FileInputStream/FileOutputStream为BufferedInputStream和BufferedOutputStream,降低磁盘IO的频繁调用:
      try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(htmlSource));
           BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(pdfDest))) {
          HtmlConverter.convertToPdf(bis, bos, converterProperties);
      }
      
    • 直接传入文件对象:优先使用HtmlConverter.convertToPdf(htmlSource, pdfDest, converterProperties),iText对文件路径的处理有内置优化,比流处理更高效。
  • 字体预处理
    • 预加载所需字体:提前添加常用字体到FontProvider,避免转换过程中反复读取字体文件:
      DefaultFontProvider fontProvider = new DefaultFontProvider();
      fontProvider.addFont("/path/to/your/regular-font.ttf");
      converterProperties.setFontProvider(fontProvider);
      
    • 优先使用PDF内置字体:如Helvetica、Times Roman,减少字体嵌入的时间和PDF体积。

针对6-7MB大HTML文件的专项处理

  • 分段转换+PDF合并
    • 将大HTML拆分为多个独立片段(按章节、分页标记拆分),逐个转换为小PDF后用PdfMerger合并,降低单次转换的内存压力:
      List<File> splitHtmlFiles = Arrays.asList(new File("part1.html"), new File("part2.html"));
      try (PdfWriter writer = new PdfWriter("merged_output.pdf");
           PdfDocument mergedPdf = new PdfDocument(writer)) {
          PdfMerger merger = new PdfMerger(mergedPdf);
          ConverterProperties props = new ConverterProperties();
          props.setMemorySavingMode(true);
      
          for (File htmlPart : splitHtmlFiles) {
              ByteArrayOutputStream tempStream = new ByteArrayOutputStream();
              try (PdfDocument tempPdf = new PdfDocument(new PdfWriter(tempStream))) {
                  HtmlConverter.convertToPdf(new FileInputStream(htmlPart), tempPdf, props);
              }
              try (PdfDocument tempPdfToMerge = new PdfDocument(new PdfReader(new ByteArrayInputStream(tempStream.toByteArray())))) {
                  merger.merge(tempPdfToMerge, 1, tempPdfToMerge.getNumberOfPages());
              }
          }
      }
      
  • 启用内存节省模式
    • 在ConverterProperties中开启内存优化:converterProperties.setMemorySavingMode(true),iText会采用流式处理策略,减少内存占用。
  • 调整JVM堆内存
    • 增大JVM堆内存参数(如-Xmx4G,根据服务器配置调整),避免大文件转换时因内存不足导致频繁GC拖慢速度。

优化后的完整示例代码

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.font.DefaultFontProvider;
import com.itextpdf.html2pdf.media.MediaDeviceDescription;
import com.itextpdf.html2pdf.media.MediaType;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfMerger;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

public class LargeHtmlToPdf {
    public static void main(String[] args) throws IOException {
        // 单大文件优化转换
        File htmlSource = new File("input.html");
        File pdfDest = new File("output.pdf");

        ConverterProperties converterProperties = new ConverterProperties();
        converterProperties.setMemorySavingMode(true);
        converterProperties.setCharset(StandardCharsets.UTF_8.name());
        converterProperties.setMediaDeviceDescription(new MediaDeviceDescription(MediaType.PRINT));
        
        DefaultFontProvider fontProvider = new DefaultFontProvider(false, false, false);
        fontProvider.addStandardPdfFonts();
        converterProperties.setFontProvider(fontProvider);

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(htmlSource));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(pdfDest))) {
            HtmlConverter.convertToPdf(bis, bos, converterProperties);
        }

        // 超大型文件分段转换合并
        List<File> splitHtmlParts = Arrays.asList(new File("part1.html"), new File("part2.html"));
        try (PdfWriter mergedWriter = new PdfWriter("merged_output.pdf");
             PdfDocument mergedPdf = new PdfDocument(mergedWriter)) {
            PdfMerger merger = new PdfMerger(mergedPdf);
            ConverterProperties partProps = new ConverterProperties();
            partProps.setMemorySavingMode(true);
            partProps.setFontProvider(fontProvider);

            for (File part : splitHtmlParts) {
                ByteArrayOutputStream tempBaos = new ByteArrayOutputStream();
                try (PdfDocument tempPdf = new PdfDocument(new PdfWriter(tempBaos))) {
                    HtmlConverter.convertToPdf(new FileInputStream(part), tempPdf, partProps);
                }
                try (PdfDocument tempPdfToMerge = new PdfDocument(new PdfReader(new ByteArrayInputStream(tempBaos.toByteArray())))) {
                    merger.merge(tempPdfToMerge, 1, tempPdfToMerge.getNumberOfPages());
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:25:34