合并两个 pdf 时不再有链接和锚点
No more links and anchors when merging two pdfs
我们使用 iText 7.1.0 和 html2pdf 2.0.0 创建了一个应用程序来构建我们的 pdf。
在我们的第一次迭代中,我们向它发送一个 data-object,其中包括 header、body 和页脚的 html,此外还包括 meta-data,如标题等。
html-body 包括 2 个部分:details-part 和 table-part。
到目前为止一切正常,links 和锚点的样式和可点击,meta-data 设置正确(除此之外:我们的 header html,有一个徽标,但我们无法围绕它构建 link。
我们更改了应用程序的行为:现在我们将 data-object 中的 collection 放入应用程序(details-part 和 table-part 分开;每个 data-objects 包括 html 用于 header、body 和页脚,还有 meta-data)。我们遍历 collection,使用之前运行良好的相同方法并将两部分合并在一起。
现在 link 和锚点已设置样式但不再可点击。我们也看不到 meta-data。构建合并时我们有什么问题吗?
控制器:
public byte[] index(@RequestBody PDFDataModelCollection elements, Model model) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
try (PdfDocument resultDoc = new PdfDocument(writer)) {
for (PDFDataModel pdfDataModel : elements.getElements()) {
PdfReader reader = new PdfReader(new ByteArrayInputStream(creationService.createDatasheet(pdfDataModel)));
try (PdfDocument sourceDoc = new PdfDocument(reader)) {
int n = sourceDoc.getNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = sourceDoc.getPage(i).copyTo(resultDoc);
resultDoc.addPage(page);
}
}
}
}
return byteArrayOutputStream.toByteArray();
}
方法 createDatasheet():
public byte[] createDatasheet(PDFDataModel pdfDataModel) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
//Initialize PDF document
PdfDocument pdfDoc = new PdfDocument(writer);
try (
Document document = new Document(pdfDoc)
) {
document.setMargins(0, 0, 0, 0);
//meta tags
PDFMetaService.addPdfMetaTags(pdfDoc, pdfDataModel.getMetaModel());
Header header = new Header(document, this.fontProvider, pdfDataModel.getHeader());
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, header);
pdfDoc.addEventHandler(PdfDocumentEvent.INSERT_PAGE, header);
Footer footer = new Footer(document, this.fontProvider, pdfDataModel.getFooter());
pdfDoc.addEventHandler(PdfDocumentEvent.INSERT_PAGE, footer);
//watermark
PDFImageModel pdfImageModel = pdfDataModel.getImageModel();
if (pdfImageModel != null) {
Watermark watermark = new Watermark(document, pdfImageModel);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, watermark);
}
//body
for (IElement element : HtmlConverter.convertToElements(pdfDataModel.getBody(), this.props)) {
document.add((IBlockElement) element);
}
footer.writeTotalNumberOnPages(pdfDoc);
}
return byteArrayOutputStream.toByteArray();
}
pdfDataModel.getMetaModel()、pdfDataModel.getHeader()、pdfDataModel.getBody()等返回setter/getter类; html 存储在那里。
任何建议都会有所帮助...
我们已将控制器更改为此,现在可以使用了:
@RequestMapping(value = "/pdf", method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public byte[] index(@RequestBody PDFDataModelCollection pdfDataCollection, Model model) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
try (PdfDocument resultDoc = new PdfDocument(writer)) {
LOGGER.debug("Parsing {} element(s) from PDFDataModelCollection.", pdfDataCollection.getElements().size());
for (PDFDataModel pdfDataModel : pdfDataCollection.getElements()) {
PdfReader reader = new PdfReader(new ByteArrayInputStream(creationService.createDatasheet(pdfDataModel)));
PdfDocument sourceDoc = new PdfDocument(reader);
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), resultDoc, resultDoc.getNumberOfPages()+1);
}
PDFMetaService.addPdfMetaTags(resultDoc, pdfDataCollection.getElements().get(1).getMetaModel());
}
return byteArrayOutputStream.toByteArray();
}
我们使用 iText 7.1.0 和 html2pdf 2.0.0 创建了一个应用程序来构建我们的 pdf。 在我们的第一次迭代中,我们向它发送一个 data-object,其中包括 header、body 和页脚的 html,此外还包括 meta-data,如标题等。
html-body 包括 2 个部分:details-part 和 table-part。
到目前为止一切正常,links 和锚点的样式和可点击,meta-data 设置正确(除此之外:我们的 header html,有一个徽标,但我们无法围绕它构建 link。
我们更改了应用程序的行为:现在我们将 data-object 中的 collection 放入应用程序(details-part 和 table-part 分开;每个 data-objects 包括 html 用于 header、body 和页脚,还有 meta-data)。我们遍历 collection,使用之前运行良好的相同方法并将两部分合并在一起。
现在 link 和锚点已设置样式但不再可点击。我们也看不到 meta-data。构建合并时我们有什么问题吗?
控制器:
public byte[] index(@RequestBody PDFDataModelCollection elements, Model model) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
try (PdfDocument resultDoc = new PdfDocument(writer)) {
for (PDFDataModel pdfDataModel : elements.getElements()) {
PdfReader reader = new PdfReader(new ByteArrayInputStream(creationService.createDatasheet(pdfDataModel)));
try (PdfDocument sourceDoc = new PdfDocument(reader)) {
int n = sourceDoc.getNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = sourceDoc.getPage(i).copyTo(resultDoc);
resultDoc.addPage(page);
}
}
}
}
return byteArrayOutputStream.toByteArray();
}
方法 createDatasheet():
public byte[] createDatasheet(PDFDataModel pdfDataModel) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
//Initialize PDF document
PdfDocument pdfDoc = new PdfDocument(writer);
try (
Document document = new Document(pdfDoc)
) {
document.setMargins(0, 0, 0, 0);
//meta tags
PDFMetaService.addPdfMetaTags(pdfDoc, pdfDataModel.getMetaModel());
Header header = new Header(document, this.fontProvider, pdfDataModel.getHeader());
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, header);
pdfDoc.addEventHandler(PdfDocumentEvent.INSERT_PAGE, header);
Footer footer = new Footer(document, this.fontProvider, pdfDataModel.getFooter());
pdfDoc.addEventHandler(PdfDocumentEvent.INSERT_PAGE, footer);
//watermark
PDFImageModel pdfImageModel = pdfDataModel.getImageModel();
if (pdfImageModel != null) {
Watermark watermark = new Watermark(document, pdfImageModel);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, watermark);
}
//body
for (IElement element : HtmlConverter.convertToElements(pdfDataModel.getBody(), this.props)) {
document.add((IBlockElement) element);
}
footer.writeTotalNumberOnPages(pdfDoc);
}
return byteArrayOutputStream.toByteArray();
}
pdfDataModel.getMetaModel()、pdfDataModel.getHeader()、pdfDataModel.getBody()等返回setter/getter类; html 存储在那里。
任何建议都会有所帮助...
我们已将控制器更改为此,现在可以使用了:
@RequestMapping(value = "/pdf", method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public byte[] index(@RequestBody PDFDataModelCollection pdfDataCollection, Model model) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
try (PdfDocument resultDoc = new PdfDocument(writer)) {
LOGGER.debug("Parsing {} element(s) from PDFDataModelCollection.", pdfDataCollection.getElements().size());
for (PDFDataModel pdfDataModel : pdfDataCollection.getElements()) {
PdfReader reader = new PdfReader(new ByteArrayInputStream(creationService.createDatasheet(pdfDataModel)));
PdfDocument sourceDoc = new PdfDocument(reader);
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), resultDoc, resultDoc.getNumberOfPages()+1);
}
PDFMetaService.addPdfMetaTags(resultDoc, pdfDataCollection.getElements().get(1).getMetaModel());
}
return byteArrayOutputStream.toByteArray();
}