iText 如何同时使用 PdfWriterPipeline 和 PdfSmartCopy?
iText how to use PdfWriterPipeline and PdfSmartCopy at the same time?
我正在使用 iText
将 HTML 转换为 PDF 文件。我意识到输出文件太大,所以我决定使用 PdfSmartCopy
来删除对象重复。我可以在 HTML-to-PDF 过程完成后使用 PdfSmartCopy
,例如,我使用 PdfSmartCopy
从磁盘加载文件并将 PDF 转换为更小的尺寸。
我的问题是,我可以简化 PdfSmartCopy
和 HTML 到 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的想法,在HTML-to-PDF渲染的时候,我把它存入了内存,后面用PdfSmartCopy
生成slim pdf版本,这样可以防止我生成文件系统中有两个不同的pdf文件(后来很难删除非slim的),如果对其他人有帮助,请粘贴下面的代码:
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();
}
我正在使用 iText
将 HTML 转换为 PDF 文件。我意识到输出文件太大,所以我决定使用 PdfSmartCopy
来删除对象重复。我可以在 HTML-to-PDF 过程完成后使用 PdfSmartCopy
,例如,我使用 PdfSmartCopy
从磁盘加载文件并将 PDF 转换为更小的尺寸。
我的问题是,我可以简化 PdfSmartCopy
和 HTML 到 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的想法,在HTML-to-PDF渲染的时候,我把它存入了内存,后面用PdfSmartCopy
生成slim pdf版本,这样可以防止我生成文件系统中有两个不同的pdf文件(后来很难删除非slim的),如果对其他人有帮助,请粘贴下面的代码:
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();
}