PDF (динамический XFA) с программным изменением поля с помощью iTextSharp выдает ошибку SOM при открытии - PullRequest
2 голосов
/ 10 июля 2019

Используя метод iText, pdfStamper.AcroFields.SetField ("target", "value") установит в поле "target" желаемое "значение".Но полученный PDF при открытии в Reader выдает ошибку выражения SOM.

Код, использующий AcroFields.Xfa.FindDatasetsNode ("target"), создает и добавляет текстовый узел (например, node.OwnerDocument.CreateTextNode(«новый текст»)) с последующим добавлением к найденному узлу (например, foundNode.AppendChild (text), также происходит сбой.

Единственное, что мне удалось сделать, - это сохранить всеPDF DOM (например, doc = pdfReader.AcroFields.Xfa.DomDocument; doc.Save (writer)), затем загрузите этот DOM в другую переменную, измените его и сохраните обратно в pdfStamp.AcroFields.Xfa.DomDocument.

Но я получаю PDF с отключенными «расширенными функциями» - несмотря на то, что я использую «режим добавления» при открытии штампа (например, pdfStamp = new PdfStamper (pdfReader, pdfStampMS, '\ 0'), true ).

Вот код:

using System;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.xml;
using System.IO;
using System.Text;
using System.Xml;

string srcPDF = "c:\\Temp\\PDF\\A3.pdf";
string destPDF = "c:\\Temp\\PDF\\A3-out10.pdf";

PdfReader pdfReader = new PdfReader(srcPDF);    
MemoryStream pdfStampMS = new MemoryStream();
PdfStamper pdfStamp = null;
pdfStamp = new PdfStamper(pdfReader, pdfStampMS, '\0', true);

AcroFields form = pdfStamp.AcroFields;
string s = form.GetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]");
//Checking, and this does get the value
form.SetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]", "XYZtest");
s = form.GetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]");
//Checking again, and this does set the value
pdfStamp.AcroFields.Xfa.Changed = true;
pdfStamp.AcroFields.Xfa.FillXfaForm(pdfStamp.AcroFields.Xfa.DatasetsNode, true);
pdfStamp.Close();
byte[] content = pdfStampMS.ToArray();
using (var fs = File.Create(destPDF))
{
fs.Write(content, 0, (int)content.Length);
}
pdfReader.Close();

Запрошенное поле получает желаемое значение, но при открытии результирующий PDF-файл выдает это исключение: "SOM выражение 'sfAssigneeEmail 'для datRef, указанного в поле' sfAssigneeEmail ', разрешенного в несовместимый тип узла' dataValue '.'

«Расширенные функции» также набираются.

Существует множество вопросов, таких какэто и большинство ответов, касающихся вопроса «расширенных возможностей», просто заявляют «использовать режим добавления» - что, я полагаю, я делаю.Больше всего беспокоит этот искаженный PDF-файл, который создается - я не видел никого, у кого есть проблема, о которой идет речь.

Любая помощь или предложения, которые очень ценятся!

ОБНОВЛЕНИЕ

Я понял проблему, и, как всегда, это было просто невежество с моей стороны.Я так и не понял, для чего предназначен код:

pdfStamp.AcroFields.Xfa.FillXfaForm(pdfStamp.AcroFields.Xfa.DatasetsNode, true);

.Я предположил, что это было какое-то волшебное заклинание, чтобы pdfStamper справился со своей работой.Это не.На самом деле, это очень полезный зверь, который позволяет вам автоматически изменять поля на основе предоставленного вами XML-документа.

Как только я понял это, исправление стало очевидным: удалите эту оскорбительную строку кода (например, строку pdfStamp.AcroFields.Xfa.FillXfaForm (pdfStamp.AcroFields.Xfa.DatasetsNode, true)).Сделайте это, и все отлично.

Пересмотренный код будет выглядеть так:

using System;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.xml;
using System.IO;
using System.Text;
using System.Xml;

string srcPDF = "c:\\Temp\\PDF\\Input.pdf";
string destPDF = "c:\\Temp\\PDF\\Output.pdf";

PdfReader pdfReader = new PdfReader(srcPDF);    
MemoryStream pdfStampMS = new MemoryStream();
PdfStamper pdfStamp = null;
pdfStamp = new PdfStamper(pdfReader, pdfStampMS, '\0', true);

AcroFields form = pdfStamp.AcroFields;
string s = form.GetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]");
//Checking, and this does get the value
form.SetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]", "XYZtest");
s = form.GetField("us - request[0].ContentArea1[0].sfApplicantInformation[0].sfApplicantName[0].firstName[0]");
//Checking again, and this does set the value
pdfStamp.AcroFields.Xfa.Changed = true;
pdfStamp.Close();
byte[] content = pdfStampMS.ToArray();
using (var fs = File.Create(destPDF))
{
fs.Write(content, 0, (int)content.Length);
}
pdfReader.Close();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...