连接pdf而不展平,但保留字段
我试图填写一个pdf模板,并在最后添加另一个pdf。 我可以将页面添加到另一个pdf,但问题是,当我这样做时,即使我不使用stamper.setFormFlating(true),我的字段也会丢失 这是我的代码:连接pdf而不展平,但保留字段,pdf,itext,flatten,Pdf,Itext,Flatten,我试图填写一个pdf模板,并在最后添加另一个pdf。 我可以将页面添加到另一个pdf,但问题是,当我这样做时,即使我不使用stamper.setFormFlating(true),我的字段也会丢失 这是我的代码: import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.ParseE
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
public class ForStack {
public static void main(String[] args) throws IOException, DocumentException, ParseException {
createContractWithMoreFile();
}
public static void createContractWithMoreFile()
throws IOException, DocumentException, ParseException {
String linkPDF = "resources/pdfs/User.pdf";
PdfReader reader = new PdfReader(linkPDF);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
PdfWriter writer = stamper.getWriter();
writer.setPdfVersion(PdfWriter.VERSION_1_7);
AcroFields form = stamper.getAcroFields();
form.setField("Name", "Jhon");
stamper.close();
String out = "results/merged.pdf";
List<byte[]> listOfPdfFiles = new ArrayList<>();
listOfPdfFiles.add(baos.toByteArray());
byte[] informativaPrivacy = getPdfByteArray("resources/pdfs/second.pdf");
listOfPdfFiles.add(informativaPrivacy);
concatenatePdfs(listOfPdfFiles, new File(out));
baos.close();
reader.close();
}
public static byte[] getPdfByteArray(String filePath) {
File fileP = new File(filePath);
byte[] result;
try {
result = FileUtils.readFileToByteArray(fileP);
return result;
} catch (IOException e) {
return null;
}
}
public static void concatenatePdfs(List<byte[]> listOfPdfFiles, File outputFile) throws DocumentException, IOException {
Document document = new Document();
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfCopy copy = new PdfSmartCopy(document, outputStream);
document.open();
for (byte[] inFile : listOfPdfFiles) {
PdfReader reader = new PdfReader(inFile);
copy.addDocument(reader);
reader.close();
}
document.close();
}
}
import java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.text.ParseException;
导入java.util.ArrayList;
导入java.util.List;
导入org.apache.commons.io.FileUtils;
导入com.itextpdf.text.Document;
导入com.itextpdf.text.DocumentException;
导入com.itextpdf.text.pdf.AcroFields;
导入com.itextpdf.text.pdf.PdfCopy;
导入com.itextpdf.text.pdf.PdfReader;
导入com.itextpdf.text.pdf.PdfSmartCopy;
导入com.itextpdf.text.pdf.PdfStamper;
导入com.itextpdf.text.pdf.PdfWriter;
公开课预赛{
公共静态void main(字符串[]args)引发IOException、DocumentException、ParseException{
createContractWithMoreFile();
}
public static void createContractWithMoreFile()
抛出IOException、DocumentException、ParseException{
String linkPDF=“resources/pdfs/User.pdf”;
PdfReader reader=新PdfReader(linkPDF);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
PdfStamper压模=新PdfStamper(读卡器,BAS);
PdfWriter writer=stamper.getWriter();
writer.setPdfVersion(PdfWriter.VERSION_1_7);
AcroFields form=stamp.getAcroFields();
设置域(“名称”、“Jhon”);
压模关闭();
String out=“results/merged.pdf”;
List-listopfdffiles=new-ArrayList();
添加(baos.toByteArray());
byte[]informativaPrivacy=getPdfByteArray(“resources/pdfs/second.pdf”);
添加(informativaPrivacy);
连接EPDF(列表OFPDF文件,新文件(输出));
baos.close();
reader.close();
}
公共静态字节[]getPdfByteArray(字符串文件路径){
File fileP=新文件(filePath);
字节[]结果;
试一试{
结果=FileUtils.readFileToByteArray(fileP);
返回结果;
}捕获(IOE异常){
返回null;
}
}
公共静态void concatenatePdfs(List ListOfDfFiles,File outputFile)引发DocumentException,IOException{
文档=新文档();
FileOutputStream outputStream=新的FileOutputStream(outputFile);
PdfCopy copy=新的PdfSmartCopy(文档、输出流);
document.open();
for(字节[]填充:ListOffDFFiles){
PdfReader读取器=新PdfReader(填充);
副本。添加文件(读卡器);
reader.close();
}
document.close();
}
}
这是我正在使用的文件
输出文件不是我想要的:
那么为什么输出pdf会丢失我的字段呢?没有连接,就没有平坦化
正如您在我的结果文件中看到的,没有字段,因此如果您不想再次看到它,我必须使用adobe Acrobat,使用->查看(Vista)->工具(Importazioni)->创建表单(Prepara Modulo)。
但如果我这样做并试图退出pdf,Adobe会要求我保存它更改的pdf,这不是我想要的
我想要的输出pdf在这里:
使用结果文件中丢失的字段
您的代码中有许多错误。例如:您不需要
org.w3c.dom.Document
,您需要com.itextpdf.text.Document
;此错误导致您的代码甚至无法编译
我修复了错误,最终得到了这个SSCCE:
package sandbox.merge;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
public class ForStack {
public static void main(String[] args) throws IOException, DocumentException, ParseException {
createContractWithMoreFile();
}
public static void createContractWithMoreFile()
throws IOException, DocumentException, ParseException {
String linkPDF = "resources/pdfs/User.pdf";
PdfReader reader = new PdfReader(linkPDF);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
PdfWriter writer = stamper.getWriter();
writer.setPdfVersion(PdfWriter.VERSION_1_7);
AcroFields form = stamper.getAcroFields();
form.setField("Name", "Jhon");
stamper.setFormFlattening(true);
stamper.close();
String out = "results/merged.pdf";
List<byte[]> listOfPdfFiles = new ArrayList<>();
listOfPdfFiles.add(baos.toByteArray());
byte[] informativaPrivacy = getPdfByteArray("resources/pdfs/second.pdf");
listOfPdfFiles.add(informativaPrivacy);
concatenatePdfs(listOfPdfFiles, new File(out));
baos.close();
reader.close();
}
public static byte[] getPdfByteArray(String filePath) {
File fileP = new File(filePath);
byte[] result;
try {
result = FileUtils.readFileToByteArray(fileP);
return result;
} catch (IOException e) {
return null;
}
}
public static void concatenatePdfs(List<byte[]> listOfPdfFiles, File outputFile) throws DocumentException, IOException {
Document document = new Document();
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfCopy copy = new PdfSmartCopy(document, outputStream);
document.open();
for (byte[] inFile : listOfPdfFiles) {
PdfReader reader = new PdfReader(inFile);
copy.addDocument(reader);
reader.close();
}
document.close();
}
}
代码中缺少该行,这解释了为什么表单没有展平
总结:
当您展平表单时,您有:
这里曾经是字段“Name”
,我们看到了值“Jhon”
,但字段本身消失了:这就是展开的意义:删除所有交互
如果不展平表单,则会出现以下情况:
互动领域仍然存在,没有平台。它是用值“Jhon”
填写的
OP似乎希望像第一个屏幕截图中那样展平表单,同时保持第二个屏幕截图中的字段。这是一种反驳。如果需要答案,OP应澄清预期结果
iText版本
顺便说一下:我用iText 5.5.13来测试这个。请注意,iText 5不再受支持,除非您是付费客户。当前版本为iText 7.1.2,但在7.1.2中,
PdfStamper
类不再存在。在iText 7中,填写表单和合并文档的方式有所不同。Bruno的回答最初假设为压模。来自OP原始代码的setFormFlatting(true)
调用表明表单应该被压平。事实证明,情况并非如此,这些字段本应保留下来
因此,Bruno删除了表单展平线,并指出结果现在是可编辑的,即表单字段存在。但是OP仍然坚持说他们已经走了
事实证明,两人都是对的,每个人都有自己的方式。区别在于:表单字段作为页面上的小部件注释出现在输出中,但是AcroForm表单定义消失了
要使iText 5.5.xPdfCopy
实例在包含所有复制源文档的合并表单字段的目标文档中创建一个AcroForm表单定义,必须激活其合并字段模式
如果您想知道为什么此模式在默认情况下不处于活动状态:它有一个缺点,所有源PdfReader
对象必须保持打开状态,直到目标PdfCopy
实例关闭,这可能会导致子对象
stamper.setFormFlattening(true);