我尝试使用PdfCopy创建基于另一个的新pdf文件。 生成过程中一切正常,生成的文件可以在我的桌面上打开而没有任何问题,但文件似乎已损坏,我必须使用的服务不能接受:
调用'签名&#39>时出现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);
我尝试上传&#34; mergedDocument&#34;而不是&#34; completedDocument&#34;我的服务接受了它,所以我很确定它与这部分有关:
for (int page = 1; page <= pdfPageNumber; page++)
{
if (!excludedPages.Any(s => s == page))
{
copy.AddPage(copy.GetImportedPage(pdfReader, page));
}
}
或pdfCopy init
答案 0 :(得分:0)
您从表单开始。您填写表格并将其展平。通过展平它,你故意抛弃所有交互性。我很惊讶您对文件越来越小感到惊讶:您正在丢弃表单基础架构!
然后,您将展平文件上传到我们未知的某项服务。这项服务抱怨:
调用&#39;签名&#39>时出现SignService错误,可能是由于文件格式错误造成的。
由于我们不知道您在谈论哪种服务,我们只能猜测。有根据的猜测是原始表单包含需要由签名服务签名的签名字段。
显然这个领域已经消失了:你把表格弄平了!我可能错了,但我认为该服务还试图读取你填写的字段,但那不会是当你抛弃所有交互性时可能。请删除以下一行:
pdfStamper.FormFlattening = true;
然后是克里斯&#39;评论:您似乎正在使用PdfCopy
。如果您使用的是旧版iTextSharp(在iText 5.5.1之前),您不应期望保留该表单。如果您使用的是最新版本,则应指示PdfCopy
保留表单(但缺少该行)。您不需要询问&#39;我如何保留表单?&#39; 因为您不应该使用PdfCopy
。
您只需要PdfStamper
。您已使用PdfStamper
填写字段,现在您还可以使用selectPages()
方法选择要保留的页面(或排除要删除的页面)。
最后,目前还不清楚你写作时的意思:
缺少数据的一些重要部分,尤其是一大堆xml。
您是说该表单不是纯AcroForm,但它还包含XFA流吗?如果是这样,那么你绝对不能使用PdfCopy
。