Лучший способ создания/заполнения печатных форм и pdf файлов?
У нас есть приложение С#, которое должно печатать сложные формы. Такие вещи, как многостраничные формы соответствия правительствам, которые должны быть в определенном формате. Мы можем получить PDF-копии этих форм и создать поля формы, но не уверены, как заполнить эти данные и создать PDF файл, который можно автоматически распечатать и отправить нашим клиентам (им нужны бумажные копии).
Кроме того, некоторые из форм являются динамическими, так как некоторые страницы должны повторяться (например, для отчета аудита о равных возможностях сотрудника нам может потребоваться включить 5 экземпляров страницы в форму, если она содержит 50 сотрудников, но клиент имеет 250).
В общем, какой лучший способ заполнить и распечатать эти формы? Обратите внимание, что наше приложение основано на С#, но любое решение на любом языке/приложении приветствуется (мы открыты для покупки программного обеспечения или интеграции с другими фреймами, если это необходимо).
Например, что бы использовало использование TurboTax для печати сотен налоговых форм, которые он обрабатывает?
Ответы
Ответ 1
Здесь есть несколько вариантов.
1) FDF, Формат данных формы. И это ужасный spec-документ, он охватывает только небольшую (редко используемую, сложную) часть формата FDF. Файлы FDF довольно тривиальны для генерации и содержат кучу пар полей/значений (и могут содержать параметры списка и другие вещи, которые вам не нужны) и ассоциация файлов. Открытие FDF заполняет PDF (через ассоциацию файлов с acrobat/reader).
Здесь образец (с дополнительными пробелами, чтобы сделать его более читаемым):
%FDF-1.2
1 0 obj
<< /FDF
<< /Fields [
<< /V (Communications Co.)/T (Address1)>>
<< /V (29 Communications Road)/T (Address2)>>
<< /V (Busyville)/T (City)>>
<< /V (USA)/T (Country)>>
<< /V (24 January 2000)/T (Date)>>
<< /V (Suzie Smith)/T (Name)>>
<< /V (\(807\) 221-9999)/T (PhoneNumber)>>
<< /V (777-11-8888)/T (SSN)>>
<< /V (NJ)/T (State)>>
]
/F (TestForm.pdf)
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF
"/V" указывает значение поля, "/T" - заголовок поля. "/F" - это путь к заполняемой форме.
Существует множество продуктов с mail-merge-esque, которые могут перемещаться по FDF и PDF и создавать заполненную форму PDF. Вышеупомянутый iText (и несколько других) могут делать это программно, другие приложения имеют командные строки.
Любая страница, которая может потребоваться повторить, должна быть собственной формой в этой среде. Слияние форм может быть довольно сложным. Есть пара подходов, причем самыми легкими из них являются "сглаживание" полей, поэтому они представляют собой только содержимое страницы (линейное искусство и текст)... тогда вы больше не сливаете PDF-формы.
Конечно, если вы можете контролировать порядок, в котором печатаются вещи, вам совсем не нужно объединять формы. Вы можете просто открыть/распечатать их в правильном порядке.
Насколько я помню, командные команды Acrobat Pro могут импортировать данные FDF и распечатывать. Все, что вам нужно сделать, это генерировать соответствующие файлы FDF, что в основном является тривиальной строкой.
Использование FDF предполагает, что вы уже создали формы PDF, просто ожидая их заполнения. Если это не так...
2) Создавайте ваши формы PDF программно. Я делаю это с iText (базой Java для iTextSharp), хотя на разных языках имеется довольно много библиотек. iText [Sharp] лицензируется под AGPL (или коммерчески). С AGPL любой, у кого есть доступ к вашему OUTPUT, должен иметь доступ к источнику вашего приложения. AGPL является "вирусом" как обычный GPL. Старые версии были доступны в MPL.
Учитывая, что это строго внутреннее и что вы будете печатать PDF файлы, лицензирование не является проблемой.
Было бы значительно более эффективно создавать шаблоны форм, а затем заполнять их... напрямую или через FDF.
Ответ 2
Вы можете попробовать Docotic.Pdf Library. Эта библиотека позволяет заполнять формы в существующих документах, импортировать и экспортировать данные FDF, а также изменять существующие документы и создавать формы с нуля.
Несколько образцов:
Как заполнить существующие формы
Как импортировать FDF в PDF-документ
Как создать текстовые поля
Docotic.Pdf поставляется с коммерческими и бесплатными лицензиями.
Ответ 3
- Распечатайте форму PDF (в высоком качестве)
- Сканировать (в высоком качестве)
- Преобразование отсканированного файла в растровое изображение (*.dib)
- Использование Visual C (VS 2010, программно)
- установить свойства страницы (т.е. подготовить страницу, контекст устройства и т.д.).
- создайте свои шрифты (сколько угодно, конечно)
- установить начало страницы (вверху страницы)
- загрузите и используйте StretchDIBits (или подобное) для печати изображения в формате PDF
- перейти к началу страницы
- вычислить положение печати (pt.x и pt.y)
- печать с помощью pDC- > TextOut (или что-то еще, что вы хотите использовать)
Вышеописанное работает с любым количеством полей на любой странице PDF, но требует
некоторые рудиментарные знания об основных процессах печати ОС.
Это дает вам полный контроль над страницей, и это означает, что вы можете перечеркнуть, распечатать и т.д.... вы можете делать все, что захотите.
Я не вижу никакой проблемы в преобразовании этого в VS 2017 и С#.
Никакой библиотеки не нужно - просто старомодное кодирование вручную.
Ответ 4
Если ваша форма основана на технологии AcroForm: просто используйте itext7 для выполнения этой задачи. Добавьте его в свой проект, выполнив следующую команду в консоли диспетчера пакетов NuGet:
Install-Package itext7
Чтобы написать конкретное поле формы, используйте код, подобный следующему:
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
var form = PdfAcroForm.GetAcroForm(pdfDoc, true);
var fields = form.GetFormFields();
fields.Get(key).SetValue(value);
form.FlattenFields();
pdfDoc.Close();
В этом фрагменте src
является источником файла PDF, а dest
является путем к полученному PDF. key
соответствует имени поля в вашем шаблоне. value
соответствует значению, которое вы хотите заполнить. Если вы хотите, чтобы форма сохраняла свою интерактивность, вам нужно удалить form.flattenFields();
, в противном случае все поля формы будут удалены, что приведет к получению плоского PDF.
Внимание
Имейте в виду, что itext7 распространяется по лицензии AGPL и не является бесплатным для коммерческого использования или закрытого источника. (отдельное спасибо @da_berni за эту необходимую информацию)
Ответ 5
Частичный ответ на ваш вопрос заключается в том, что вам следует изучить библиотеку "ItextSharp", которая является библиотекой с открытым исходным кодом и полезна при создании файлов PDF.
http://sourceforge.net/projects/itextsharp/
Ответ 6
мы используем aspose.words, и я вижу, что у них также есть PDF API.
Ответ 7
Попробуйте с этим:
string Filepath = Server.MapPath("/AOF.pdf");
var pdfpath = Path.Combine(Filepath, "");
var Formcontent = ListFieldNames(Filepath);
Formcontent["Name_txt"] = "T.Test" ; FillForm(Formcontent); // var pdfContents = FillForm(pdfpath, Formcontent);
public Dictionary<string, string> ListFieldNames(string Filepath)
{
//PdfReader pdfReader = new PdfReader(pdfTemplate);
//StringBuilder sb = new StringBuilder();
//foreach(DictionaryEntry de in pdfReader.AcroFields.Fields)
//{
// sb.Append(de.Key.ToString() + Environment.NewLine);
//}
var Fileds = new Dictionary<string, string>();
PdfReader pdfReader = new PdfReader(Filepath);
var reader = new PdfReader(pdfReader);
foreach (var entry in reader.AcroFields.Fields)
Fileds.Add(entry.Key.ToString(), string.Empty);
reader.Close();
return Fileds;
}
public byte[] FillForm(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return output.ToArray();
}
public void FillForm(Dictionary<string, string> Formfiledmap)
{
string pdfTemplate = Server.MapPath("/AOF.pdf");
string newFile = @"C:\Users\USer\Desktop\completed_fw4.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
foreach (var fieldName in Formfiledmap.Keys)
pdfFormFields.SetField(fieldName, Formfiledmap[fieldName]);
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}