iText - 将内容添加到现有PDF文件

Wou*_*ens 46 java pdf itext

我想用iText做以下事情:

(1)解析现有的PDF文件

(2)在文档的现有单页上添加一些数据(例如时间戳)

(3)写出文件

我似乎无法弄清楚如何用iText做到这一点.在伪代码中,我会这样做:

Document document = reader.read(input);
document.add(new Paragraph("my timestamp"));
writer.write(document, output);
Run Code Online (Sandbox Code Playgroud)

但由于某些原因,iText的API非常复杂,我无法绕过它.PdfReader实际上保存文档模型或其他东西(而不是吐出文档),你需要一个PdfWriter来读取它的页面......呃?

gut*_*tch 71

iText有多种方法可以做到这一点.该PdfStamper课程是一种选择.但我发现最简单的方法是创建一个新的PDF文档,然后将现有文档中的各个页面导入到新的PDF中.

// Create output PDF
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cb = writer.getDirectContent();

// Load existing PDF
PdfReader reader = new PdfReader(templateInputStream);
PdfImportedPage page = writer.getImportedPage(reader, 1); 

// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);

// Add your new data / text here
// for example...
document.add(new Paragraph("my timestamp")); 

document.close();
Run Code Online (Sandbox Code Playgroud)

这将从PDF中读取templateInputStream并写出来outputStream.这些可能是文件流或内存流或任何适合您的应用程序.

  • 谢谢你.如果您不想仅限制为A4,可以添加document.setPageSize(reader.getPageSize(1)); (11认同)

Mar*_*rer 42

Gutch的代码很接近,但它只能在以下情况下正常工作:

  • 没有注释(链接,字段等),没有文档结构/标记内容,没有书签,没有文档级脚本等,等等......
  • 页面大小恰好是A.4(不错的赔率,但它不适用于碰巧碰到的任何'PDF')
  • 您不介意丢失所有原始文档元数据(生产者,创建日期,可能是作者/标题/关键字),也可能丢失文档ID.您不能复制创建日期和文档ID,除非您对iText本身做了一些非常深刻的讨论).

批准的方法是反过来做.使用PdfStamper打开现有文档,并使用getOverContent()返回的PdfContentByte将文本(以及您可能需要的任何其他内容)直接写入页面.不需要第二份文件.

并且您可以使用ColumnText来处理布局等等...无需使用beginText(),setFontAndSize(),drawText(),drawText()...,endText()进行处理.


Alf*_*red 6

这是我能想象到的最复杂的场景:我有一个用Ilustrator创建并用Acrobat修改的PDF文件,用AcroFields(AcroForm),我将用这个Java代码填充数据,这个PDF文件的结果是添加文档后,将修改字段中的数据.

实际上,在这种情况下,我动态生成一个添加到PDF的背景,该背景也是使用具有未知数据或页面数量的文档动态生成的.

我正在使用JBoss,这段代码在JSP文件中(应该可以在任何JSP Web服务器中使用).

注意:如果您使用的是IExplorer,则必须使用POST方法提交HTTP表单才能下载该文件.如果没有,您将在屏幕上看到PDF代码.这不会发生在Chrome或Firefox中.

<%@ page import="java.io.*, com.lowagie.text.*, com.lowagie.text.pdf.*" %><%

response.setContentType("application/download");
response.setHeader("Content-disposition","attachment;filename=listaPrecios.pdf" );  

// -------- FIRST THE PDF WITH THE INFO ----------
String str = "";
// lots of words
for(int i = 0; i < 800; i++) str += "Hello" + i + " ";
// the document
Document doc = new Document( PageSize.A4, 25, 25, 200, 70 );
ByteArrayOutputStream streamDoc = new ByteArrayOutputStream();
PdfWriter.getInstance( doc, streamDoc );
// lets start filling with info
doc.open();
doc.add(new Paragraph(str));
doc.close();
// the beauty of this is the PDF will have all the pages it needs
PdfReader frente = new PdfReader(streamDoc.toByteArray());
PdfStamper stamperDoc = new PdfStamper( frente, response.getOutputStream());

// -------- THE BACKGROUND PDF FILE -------
// in JBoss the file has to be in webinf/classes to be readed this way
PdfReader fondo = new PdfReader("listaPrecios.pdf");
ByteArrayOutputStream streamFondo = new ByteArrayOutputStream();
PdfStamper stamperFondo = new PdfStamper( fondo, streamFondo);
// the acroform
AcroFields form = stamperFondo.getAcroFields();
// the fields 
form.setField("nombre","Avicultura");
form.setField("descripcion","Esto describe para que sirve la lista ");
stamperFondo.setFormFlattening(true);
stamperFondo.close();
// our background is ready
PdfReader fondoEstampado = new PdfReader( streamFondo.toByteArray() );

// ---- ADDING THE BACKGROUND TO EACH DATA PAGE ---------
PdfImportedPage pagina = stamperDoc.getImportedPage(fondoEstampado,1);
int n = frente.getNumberOfPages();
PdfContentByte background;
for (int i = 1; i <= n; i++) {
    background = stamperDoc.getUnderContent(i);
    background.addTemplate(pagina, 0, 0);
}
// after this everithing will be written in response.getOutputStream()
stamperDoc.close(); 
%>
Run Code Online (Sandbox Code Playgroud)

还有另一种解决方案更简单,并解决了您的问题.这取决于您要添加的文本量.

// read the file
PdfReader fondo = new PdfReader("listaPrecios.pdf");
PdfStamper stamper = new PdfStamper( fondo, response.getOutputStream());
PdfContentByte content = stamper.getOverContent(1);
// add text
ColumnText ct = new ColumnText( content );
// this are the coordinates where you want to add text
// if the text does not fit inside it will be cropped
ct.setSimpleColumn(50,500,500,50);
ct.setText(new Phrase(str, titulo1));
ct.go();
Run Code Online (Sandbox Code Playgroud)


Ste*_* Ju 5

如何在不创建新 pdf 的情况下更新 pdf

\n

iText 7,请注意版本

\n
PdfReader reader = new PdfReader(src);\nPdfWriter writer = new PdfWriter(dest);\nPdfDocument pdfDoc = new PdfDocument(reader, writer);\n//manipulate pdf\xe2\x80\xa6\npdfDoc.close();\n
Run Code Online (Sandbox Code Playgroud)\n