Java iText如何同时使用PdfWriterPipeline和PdfSmartCopy?

Java iText如何同时使用PdfWriterPipeline和PdfSmartCopy?,java,pdf,itext,pdf-generation,Java,Pdf,Itext,Pdf Generation,我正在使用iText将HTML转换为PDF文件。我意识到输出文件太大,所以我决定使用PdfSmartCopy删除对象重复。HTML转换为PDF过程完成后,我可以使用PdfSmartCopy,如中所示,我使用PdfSmartCopy从磁盘加载文件并将PDF转换为较小的大小 我的问题是,我能否将PdfSmartCopy与HTML-to-PDF过程一起简化?我发现PdfSmartCopy是PdfWriter的一个子类。因此,我将代码更改为: public static void main(String

我正在使用
iText
将HTML转换为PDF文件。我意识到输出文件太大,所以我决定使用
PdfSmartCopy
删除对象重复。HTML转换为PDF过程完成后,我可以使用
PdfSmartCopy
,如中所示,我使用
PdfSmartCopy
从磁盘加载文件并将PDF转换为较小的大小

我的问题是,我能否将
PdfSmartCopy
与HTML-to-PDF过程一起简化?我发现
PdfSmartCopy
PdfWriter
的一个子类。因此,我将代码更改为:

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


基于@mkl idea,在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();
}
try(ByteArrayOutputStream byteData=newbytearrayoutputstream()){
文件=新文件(页面大小为A4);
PdfWriter writer=PdfWriter.getInstance(文档,字节数据);
writer.setInitialLeading(12.5f);
document.open();
CSSResolver CSSResolver=新样式AttrCSSResolver();
CssFile CssFile=xmlworkerhelp.getCSS(新文件输入流(“itext2\\css\\bootstrap.min.css”);
cssResolver.addCss(cssFile);
HtmlPipelineContext htmlContext=新的HtmlPipelineContext(null);
setTagFactory(Tags.getHtmlTagProcessorFactory());
PdfWriterPipeline pdf=新的PdfWriterPipeline(文档、编写器);
HtmlPipeline html=新的HtmlPipeline(htmlContext,pdf);
CssResolverPipeline css=新的CssResolverPipeline(cssResolver,html);
XMLWorker=newxmlworker(css,true);
XMLParser p=新的XMLParser(worker);
字符串fileContent=PdfTest.readFile(“itext2\\template.html”);
p、 解析(新StringReader(fileContent));
document.close();
PdfReader reader=新的PdfReader(byteData.toByteArray());
Document document1=新文档();
File resultFile=新文件(“result.pdf”);
PdfSmartCopy pdfCopy=newpdfsmartcopy(document1,newfileoutputstream(resultFile));
document1.open();
PDF导入页面;

对于(int pAuNeNoS= 1;PayNoNo.No),这是不可能的。您只可以将中间PDF文件文件保存在内存中,但是当您认为它的大小太大时,您可能不希望这样。