Мой работодатель в настоящее время использует 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");