使用PdfCopy从模板复制PDF(数据丢失)
本文关键字:数据 PDF 复制 PdfCopy 使用 | 更新日期: 2023-09-27 18:20:09
我正试图使用PdfCopy在另一个pdf文件的基础上创建一个新的pdf文件。生成过程中一切正常,生成的文件可以在我的桌面上打开,没有任何问题,但文件似乎已损坏,我必须使用的服务不接受:
调用"sign"时发生SignService错误,可能是由错误的文件格式引起的。
我注意到生成的pdf总是比原始模板轻,所以我将模板版本与生成的版本进行了比较。缺少的数据有很大一部分,尤其是一大堆xml。我想PdfCopy并没有复制我的所有原始pdf,但我不知道我缺少了什么。
这是我的方法:
byte[] completedDocument = null;
string originalUri = Path.Combine(this.PdfPath, pdfName);
string generatedUri = Path.Combine(this.PdfGeneratedPath, generatedPdfName);
using(MemoryStream streamCompleted = new MemoryStream())
{
using(Document doc = new Document())
{
PdfCopy copy = new PdfCopy(doc, streamCompleted);
copy.PdfVersion = PdfWriter.VERSION_1_6;
doc.Open();
copy.Open();
byte[] mergedDocument = null;
PdfReader pdfReader = new PdfReader(originalUri);
int pdfPageNumber = pdfReader.NumberOfPages;
using(MemoryStream streamTemplate = new MemoryStream())
{
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, streamTemplate))
{
AcroFields acrofields = pdfStamper.AcroFields;
foreach (KeyValuePair<string, AcroFields.Item> field in acrofields.Fields)
{
string data;
if (pdfFieldsValues.TryGetValue(field.Key, out data))
{
if (data == null)
{
data = string.Empty;
}
acrofields.SetField(field.Key, data);
}
}
pdfStamper.FormFlattening = true;
pdfStamper.Writer.CloseStream = false;
}
mergedDocument = streamTemplate.ToArray();
}
pdfReader = new PdfReader(mergedDocument);
for (int page = 1; page <= pdfPageNumber; page++)
{
if (!excludedPages.Any(s => s == page))
{
copy.AddPage(copy.GetImportedPage(pdfReader, page));
}
}
doc.Close();
copy.Close();
}
completedDocument = streamCompleted.ToArray();
}
File.WriteAllBytes(generatedUri, completedDocument);
我试图上传"mergedDocument",而不是"completedDocument",我的服务接受了它,所以我很确定它与这部分有关:
for (int page = 1; page <= pdfPageNumber; page++)
{
if (!excludedPages.Any(s => s == page))
{
copy.AddPage(copy.GetImportedPage(pdfReader, page));
}
}
或者pdfCopy init
你从一个表单开始。你填写表单并将其压平。通过压平它,你故意放弃了所有的交互性。我很惊讶你对文件变小感到惊讶:你正在扔掉表单基础结构!
然后,您将扁平文件上传到我们未知的某个服务。该服务投诉:
调用"sign"时发生SignService错误,可能是由错误的文件格式引起的。
由于我们不知道你说的是哪项服务,我们只能猜测。一个有根据的猜测是,原始表单包含一个需要由签名服务签名的签名字段。
很明显,这个字段已经不见了:你把表单弄平了我可能错了,但我认为服务也会尝试读取您填写的字段,但这也不可能,因为您放弃了所有的交互性。请删除以下行:
pdfStamper.FormFlattening = true;
然后是Chris的评论:看起来你在使用PdfCopy
。如果您使用的是旧版本的iTextSharp(iText5.5.1之前),则不应期望保留该表单。如果使用的是最新版本,则应指示PdfCopy
保留该表单(但缺少该行)。你不需要问"我如何保存表单?"因为无论如何都不应该使用PdfCopy
。
您只需要PdfStamper
。您已经使用PdfStamper
来填写字段,现在还可以使用selectPages()
方法来选择要保留的页面(或排除要删除的页面)。
最后,当你写时,还不清楚你的意思是什么
缺少的数据有很大一部分,尤其是一大堆xml。
你是说这个表单不是一个纯AcroForm,而是说它还包含一个XFA流?如果是这样,那么你肯定不能使用PdfCopy
。