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

使用iTextPDF将HTML转PDF时遇图片错误如何跳过继续转换?

解决iTextPDF转换HTML到PDF时跳过错误图片的问题

这个问题我之前碰到过,核心思路就是接管图片加载的逻辑,在加载失败的时候自定义处理逻辑,而不是让整个转换流程崩溃。下面分两种主流iText版本给你具体方案:

方案一:iText 7 及以上版本(推荐)

iText7的HtmlConverter提供了扩展接口IImageProvider,我们可以通过实现这个接口来控制图片加载的异常处理:

1. 自定义图片加载处理器

创建一个实现IImageProvider的类,在getImage方法里捕获图片加载异常,返回占位图或者直接跳过(返回null):

import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.layout.element.Image;
import com.itextpdf.html2pdf.resolver.resource.IImageProvider;
import com.itextpdf.html2pdf.ConverterProperties;
import java.io.IOException;

class CustomImageProvider implements IImageProvider {
    @Override
    public Image getImage(String src, String baseUri, ConverterProperties converterProperties) {
        try {
            // 尝试加载原始图片
            return new Image(ImageDataFactory.create(src));
        } catch (IOException e) {
            e.printStackTrace(); // 可选:记录错误日志
            // 方案1:返回一个本地占位图(推荐,用户能直观看到哪里有问题)
            try {
                return new Image(ImageDataFactory.create("path/to/your/placeholder.png"));
            } catch (IOException ex) {
                // 方案2:如果占位图也加载失败,返回null直接跳过该图片
                return null;
            }
        }
    }
}

2. 在转换时配置自定义处理器

把自定义的ImageProvider注入到ConverterProperties中,再传给转换方法:

import com.itextpdf.html2pdf.HtmlConverter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class HtmlToPdfConverter {
    public static void main(String[] args) throws IOException {
        String inputHtmlPath = "your-input.html";
        String outputPdfPath = "your-output.pdf";

        // 配置转换属性
        ConverterProperties properties = new ConverterProperties();
        properties.setImageProvider(new CustomImageProvider());

        // 执行转换
        HtmlConverter.convertToPdf(
            new FileInputStream(inputHtmlPath),
            new FileOutputStream(outputPdfPath),
            properties
        );
    }
}

方案二:iText 5.x 版本(旧版本兼容)

如果你还在使用iText5的XMLWorker来处理HTML,需要实现旧版的IImageProvider接口:

1. 自定义图片加载处理器

import com.itextpdf.text.Image;
import com.itextpdf.tool.xml.html.ImageProvider;
import java.io.IOException;

class CustomImageProvider5 implements ImageProvider {
    @Override
    public Image retrieve(String src) {
        try {
            // 尝试加载原始图片
            return Image.getInstance(src);
        } catch (Exception e) {
            e.printStackTrace(); // 记录错误日志
            // 加载失败时返回占位图或null
            try {
                return Image.getInstance("path/to/your/placeholder.png");
            } catch (Exception ex) {
                return null;
            }
        }
    }

    @Override
    public String getImageRootPath() {
        return null; // 不需要设置根路径的话返回null
    }
}

2. 配置XMLWorker使用自定义处理器

import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.HtmlPipelineContext;
import com.itextpdf.tool.xml.pipeline.css.CssResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class HtmlToPdfConverter5 {
    public static void main(String[] args) throws IOException {
        Document document = new Document(PageSize.A4);
        String outputPdfPath = "your-output.pdf";
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputPdfPath));
        document.open();

        // 配置HTML处理上下文,注入自定义图片处理器
        CssAppliers cssAppliers = new CssAppliersImpl();
        HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
        htmlContext.setImageProvider(new CustomImageProvider5());
        htmlContext.setTagFactory(com.itextpdf.tool.xml.html.Tags.getHtmlTagProcessorFactory());

        // 构建处理管道
        CssResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
        HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer));
        CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);

        // 执行转换
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, new FileInputStream("your-input.html"), cssPipeline);

        document.close();
    }
}

关键说明

  • 如果返回null,对应的<img>标签会被直接跳过,PDF中不会留下任何痕迹;
  • 返回占位图的话,能让用户清晰看到哪些图片加载失败,更利于排查问题;
  • 不管哪个版本,核心都是把图片加载的异常捕获逻辑从全局转换流程中剥离出来,放到单独的图片处理器里,这样单个图片的失败就不会导致整个转换终止。

内容的提问来源于stack exchange,提问作者yasin tavukcuoglu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:01:59