iText 7 - Исключение вне диапазона при вызове PdfFormField.SetValue или PdfAcroForm.FlattenFields - PullRequest
1 голос
/ 15 апреля 2019

Мой работодатель в настоящее время использует Classic ASP и FDF для загрузки PDF-файлов из базы данных, их заполнения и передачи в браузер. Они хотели бы создать более современную реализацию, соответствующую их новой парадигме ASP.NET Core, и поэтому мое внимание было обращено на iText 7, который, как я понял, поддерживал Core, по крайней мере экспериментально, для нескольких версий сейчас. Пример PDF, который я пытаюсь заполнить: здесь .

Следующая моя попытка. «doc» - это объект, содержащий PDF в виде байтового массива (doc.Document), а также имена полей для заполнения (doc.DocumentFields.DocFieldName) и текст, которым я хочу заполнить эти поля (doc. DocumentFields.ReplacementText).

PdfReader reader = new PdfReader(new MemoryStream(doc.Document));
MemoryStream ffoutput = new MemoryStream();
PdfWriter writer = new PdfWriter(ffoutput);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, false);
IDictionary<String, PdfFormField> fields = form.GetFormFields();

foreach (var field in fields)
{
    string key = field.Key;
    PdfFormField varField = form.GetField(key);
    DocField keyField = doc.DocumentFields.Where(p => p.DocFieldName == key).FirstOrDefault();
    if (keyField != null)
    {
        varField.SetValue(keyField.ReplacementText);
    }   
 }

 form.FlattenFields();
 pdfDoc.Close();
 doc.Document = ffoutput.ToArray();

Выполнение этого дает мне следующее исключение в строке, где я вызываю varField.SetValue ():

Exception has occurred: CLR/System.ArgumentOutOfRangeException
An exception of type 'System.ArgumentOutOfRangeException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Index was out of range. Must be non-negative and less than the size of the collection.'
   at System.ThrowHelper.ThrowArgumentOutOfRange_IndexException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at iText.Kernel.Pdf.PdfArray.Get(Int32 index, Boolean asDirect)
   at iText.Kernel.Pdf.PdfArray.GetAsNumber(Int32 index)
   at iText.Forms.Fields.PdfFormField.DrawBorder(PdfCanvas canvas, PdfFormXObject xObject, Single width, Single height)
   at iText.Forms.Fields.PdfFormField.DrawTextAppearance(Rectangle rect, PdfFont font, Single fontSize, String value, PdfFormXObject appearance)
   at iText.Forms.Fields.PdfFormField.RegenerateField()
   at iText.Forms.Fields.PdfFormField.SetValue(String value, Boolean generateAppearance)

Отметив, что это происходит из-за отрисовки внешнего вида поля, я передал «false» в необязательный параметр SetValue GenerateAppearance, после чего эта ошибка исчезла. Однако та же самая ошибка затем появилась в form.FlattenFields (). Итак, я увидел, что можно отключить генерацию появлений в FlattenFields () с помощью PdfAcroForm.SetGenerateAppearance (false), и я попробовал это. Это полностью устранило ошибку, однако полученный PDF содержал только пустые поля, за исключением пары полей с установленными значениями по умолчанию.

В этом последнем сценарии я могу установить точку останова и добавить наблюдение за varField.GetValue () после вызова SetValue (), и вижу, что значение якобы установлено в текст, который я ищу. Поэтому я предполагаю, что если бы я мог позволить используемым мной методам генерировать внешний вид так, как они хотят, то я бы, вероятно, увидел мои значения.

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

Эта проблема связана с «экспериментальной» природой поддержки программного обеспечения .Net Standard / Core? Или я делаю что-то действительно глупое? Спасибо за ваше время.

РЕДАКТИРОВАТЬ: я должен также упомянуть, что я попробовал шаблон по умолчанию, упомянутый в руководствах и получил тот же результат. Под этим я подразумеваю:

fields.TryGetValue(field, out toSet);
toSet.SetValue("0");
...