且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用iText将html转换为pdf

更新时间:2021-11-08 10:01:56

您需要实现自定义图像标记处理器来处理嵌入在html中的图像:

You need to implement a custom image tag processor to process the images embedded inside your html:

package com.example.itext.processor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.NoCustomContextException;
import com.itextpdf.tool.xml.Tag;
import com.itextpdf.tool.xml.WorkerContext;
import com.itextpdf.tool.xml.exceptions.LocaleMessages;
import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException;
import com.itextpdf.tool.xml.html.HTML;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

public class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image {

private final Logger logger = LoggerFactory.getLogger(getClass());

/*
 * (non-Javadoc)
 * 
 * @see com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag, java.util.List, com.itextpdf.text.Document)
 */
@Override
public List<Element> end(final WorkerContext ctx, final Tag tag, final List<Element> currentContent) {
    final Map<String, String> attributes = tag.getAttributes();
    String src = attributes.get(HTML.Attribute.SRC);
    List<Element> elements = new ArrayList<Element>(1);
    if (null != src && src.length() > 0) {
        Image img = null;
        if (src.startsWith("data:image/")) {
            final String base64Data = src.substring(src.indexOf(",") + 1);
            try {
                img = Image.getInstance(Base64.decode(base64Data));
            } catch (Exception e) {
                if (logger.isLogging(Level.ERROR)) {
                    logger.error(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.HTML_IMG_RETRIEVE_FAIL), src), e);
                }
            }
            if (img != null) {
                try {
                    final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx);
                    elements.add(getCssAppliers().apply(new Chunk((com.itextpdf.text.Image) getCssAppliers().apply(img, tag, htmlPipelineContext), 0, 0, true), tag,
                        htmlPipelineContext));
                } catch (NoCustomContextException e) {
                    throw new RuntimeWorkerException(e);
                }
            }
        }

        if (img == null) {
            elements = super.end(ctx, tag, currentContent);
        }
    }
    return elements;
}
}

以下代码段注册自定义图片代码处理器和隐蔽HTML文档到PDF

Following code snippet registers the custom image tag processor and coverts an HTML document to PDF

public static void main(String[] args) {
    convertHtmlToPdf();

}

private static void convertHtmlToPdf() {
    try {
        final OutputStream file = new FileOutputStream(new File("C:\\Test.pdf"));
        final Document document = new Document();
        final PdfWriter writer = PdfWriter.getInstance(document, file);
        document.open();
        final TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
        tagProcessorFactory.removeProcessor(HTML.Tag.IMG);
        tagProcessorFactory.addProcessor(new ImageTagProcessor(), HTML.Tag.IMG);

        final CssFilesImpl cssFiles = new CssFilesImpl();
        cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
        final StyleAttrCs-s-resolver cssResolver = new StyleAttrCs-s-resolver(cssFiles);
        final HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
        hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
        final HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
        final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
        final XMLWorker worker = new XMLWorker(pipeline, true);
        final Charset charset = Charset.forName("UTF-8");
        final XMLParser xmlParser = new XMLParser(true, worker, charset);
        final InputStream is = new FileInputStream("C:\\test.html");
        xmlParser.parse(is, charset);

        is.close();
        document.close();
        file.close();
    } catch (Exception e) {
        e.printStackTrace();
        // TODO
    }
}