我正在使用iText将HTML转换为PDF文件。我意识到输出文件太大,因此决定使用PdfSmartCopy删除对象重复项。在完成HTML到PDF的处理后,可以使用PdfSmartCopy,例如,我可以使用PdfSmartCopy从磁盘加载文件并将PDF转换为较小的尺寸。

我的问题是,我可以将PdfSmartCopy简化为HTML到PDF的过程吗?我发现PdfSmartCopyPdfWriter的子类。所以我将代码更改为:

public static void main(String[] args) throws Exception {
    try (OutputStream file = new FileOutputStream(new File("output.pdf"))) {

        Document document = new Document(PageSize.A4);

        //PdfWriter writer = PdfWriter.getInstance(document, file); // remove this line
        PdfSmartCopy pdfCopy = new PdfSmartCopy(document, file); // change to this line
        pdfCopy.setInitialLeading(12.5f);

        document.open();

        CSSResolver cssResolver = new StyleAttrCSSResolver();
        CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream("itext2\\css\\bootstrap.min.css"));
        cssResolver.addCss(cssFile);

        HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
        htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

        PdfWriterPipeline pdf = new PdfWriterPipeline(document, pdfCopy);
        HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
        CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

        XMLWorker worker = new XMLWorker(css, true);
        XMLParser p = new XMLParser(worker);

        String fileContent = PdfTest.readFile("itext2\\template.html");

        p.parse(new StringReader(fileContent));

        document.close();
        pdfCopy.close();
        file.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}


不幸的是,我得到以下错误:

ExceptionConverter: java.io.IOException: The document has no pages.
    at com.itextpdf.text.pdf.PdfPages.writePageTree(PdfPages.java:113)
    at com.itextpdf.text.pdf.PdfWriter.close(PdfWriter.java:1257)
    at com.itextpdf.text.pdf.PdfCopy.close(PdfCopy.java:1698)
    at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:895)
    at com.itextpdf.text.Document.close(Document.java:416)
    at pdftest.CompressPdfTest.main(CompressPdfTest.java:65)


是否可以在进行HTML到PDF渲染的同时使用PdfSmartCopy

https://api.itextpdf.com/iText5/5.5.9/com/itextpdf/text/pdf/PdfSmartCopy.html#PdfSmartCopy-com.itextpdf.text.Document-java.io.OutputStream-

最佳答案

基于@mkl的想法,在HTML到PDF渲染期间,我将其保存到内存中,以后使用PdfSmartCopy生成超薄pdf版本,这可以防止我在文件系统中生成两个不同的pdf文件(后来有麻烦删除不苗条的代码),如果有帮助,请粘贴以下代码:

try (ByteArrayOutputStream byteData = new ByteArrayOutputStream()) {

    Document document = new Document(PageSize.A4);

    PdfWriter writer = PdfWriter.getInstance(document, byteData);
    writer.setInitialLeading(12.5f);

    document.open();

    CSSResolver cssResolver = new StyleAttrCSSResolver();
    CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream("itext2\\css\\bootstrap.min.css"));
    cssResolver.addCss(cssFile);

    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

    PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
    HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
    CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

    XMLWorker worker = new XMLWorker(css, true);
    XMLParser p = new XMLParser(worker);

    String fileContent = PdfTest.readFile("itext2\\template.html");

    p.parse(new StringReader(fileContent));

    document.close();

    PdfReader reader = new PdfReader(byteData.toByteArray());
    Document document1 = new Document();
    File resultFile = new File("result.pdf");
    PdfSmartCopy pdfCopy = new PdfSmartCopy(document1, new FileOutputStream(resultFile));
    document1.open();
    PdfImportedPage page;
    for (int pageNumber = 1; pageNumber <= reader.getNumberOfPages(); pageNumber++) {
        page = pdfCopy.getImportedPage(reader, pageNumber);
        pdfCopy.addPage(page);
    }

    document1.close();
    byteData.close();
} catch (Exception e) {
    e.printStackTrace();
}

关于java - iText如何同时使用PdfWriterPipeline和PdfSmartCopy?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57847644/

10-10 16:29