C# 创建/填写打印表单和PDF的最佳方法?

C# 创建/填写打印表单和PDF的最佳方法?,c#,pdf,adobe,pdf-generation,C#,Pdf,Adobe,Pdf Generation,我们有一个C#应用程序,它必须打印复杂的表单。例如,多页政府合规表格必须采用特定格式。我们可以获取这些表单的PDF副本并创建表单字段,但不确定如何填写这些数据并创建可以自动打印并发送给客户的PDF(他们需要纸质副本) 此外,有些表单是动态的,因为某些页面必须重复(例如,对于员工机会均等审计报告,如果表单中包含50名员工,但客户有250名员工,则我们可能需要在表单中包含5份页面副本) 一般来说,填充和打印这些表单的最佳方式是什么?请注意,我们的应用程序基于C#,但欢迎使用任何语言/应用程序的任何解

我们有一个C#应用程序,它必须打印复杂的表单。例如,多页政府合规表格必须采用特定格式。我们可以获取这些表单的PDF副本并创建表单字段,但不确定如何填写这些数据并创建可以自动打印并发送给客户的PDF(他们需要纸质副本)

此外,有些表单是动态的,因为某些页面必须重复(例如,对于员工机会均等审计报告,如果表单中包含50名员工,但客户有250名员工,则我们可能需要在表单中包含5份页面副本)

一般来说,填充和打印这些表单的最佳方式是什么?请注意,我们的应用程序基于C#,但欢迎使用任何语言/应用程序的任何解决方案(如果需要,我们欢迎购买软件或与其他框架集成)


例如,TurboTax会使用什么来打印它处理的数百张税务表格

您的问题的部分答案是您应该探索“ItextSharp”库,它是一个开源库,在创建PDF文件时非常有用


这里有几个选项

1) FDF。这是一个糟糕的规范文档,它只涵盖了FDF格式的一小部分(不经常使用,很复杂)。FDF文件的生成非常简单,包含一堆字段/值对(可以保存列表选项和其他您不需要的更高级的内容)和文件关联。打开FDF将填充PDF(通过与acrobat/reader的文件关联)

下面是一个示例(带有额外的空格以使其更具可读性):

%FDF-1.2
10 obj
>
>
>
>
>
>
>
]
/F(TestForm.pdf)
>>
>>
endobj
拖车
>
%%EOF
“/V”表示字段值,“/T”是字段的标题。“/F”是要填写的表单的路径

有许多类似邮件合并的产品可以接收FDF和PDF并生成填充的PDF表单。前面提到的iText(以及其他几个应用程序)可以通过编程实现这一点,其他应用程序都有命令行

在这个环境中,任何可能需要重复的页面都应该是它自己的形式。合并表单可能相当困难。有两种方法,其中最简单的是“展平”字段,使其仅为页面内容(线条艺术和文本)。。。那么你就不再真正合并PDF表单了

当然,如果可以控制打印的顺序,则根本不需要合并表单。您可以按正确的顺序打开/打印它们

我记得,Acrobat Pro的批处理命令可以导入FDF数据并打印。您所需要做的就是生成适当的FDF文件,这大部分是琐碎的字符串构建

使用FDF假定您已经制作了PDF表单,只是等待填写。如果不是这样的话

2) 以编程方式生成PDF表单。我使用iText(iTextSharp的Java基础)来实现这一点,尽管有很多不同语言的库可用。iText[Sharp]根据AGPL获得许可(或商业许可)。使用AGPL,任何能够访问您的输出的人都必须能够访问您的应用程序源。AGPL和常规GPL一样“病毒性”。MPL下提供了旧版本

考虑到这是严格的内部操作,并且您将打印PDF,因此许可证问题不大

一旦生成表单模板,然后填写它们,效率会大大提高。。。直接或通过FDF。

您可以尝试。该库允许在现有文档中填写表单、导入和导出FDF数据,以及修改现有文档和从头创建表单

几个样本:

Pdf附带商业和免费许可证

  • 打印PDF表单(高质量)
  • 扫描(高质量)
  • 将扫描的文件转换为位图(*.dib)
  • 使用Visual C(VS 2010,编程方式)
    • 设置页面属性(即准备页面、设备上下文等)
    • 创建你的字体(当然,你喜欢多少就有多少)
    • 设置页面原点(页面顶部)
    • 加载并使用StretchDIBits(或类似工具)打印PDF页面图像
    • 转到页面顶部
    • 计算您的打印位置(第x部分和第y部分)
    • 使用pDC->TextOut打印(或您想要使用的任何其他方式)
  • 以上内容适用于任何PDF页面上的任何数量的字段,但需要 对底层操作系统打印过程的一些基本知识。 它让你完全控制页面,这意味着你可以划掉,打印,等等。。。。你可以做任何你喜欢的事。
    我认为将其转换为VS 2017和C#没有任何问题。 不需要库-只需要简单的老式手工编码

    试试这个:

    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();
    }
    
    stringfilepath=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);
    公共字典ListFieldName(字符串文件路径)
    {
    //PdfReader PdfReader=新PdfReader(pdfTemplate);
    //StringBuilder sb=新的StringBuilder();
    //foreach(pdfReader.AcroFields.Fields中的DictionaryEntry de)
    //{
    //sb.Append(de.Key.ToString()+Environment.NewLine);
    //}
    var Fileds=新字典();
    PdfReader PdfReader=新PdfReader(文件路径);
    变量读取器=新的PdfReader(PdfReader);
    foreach(reader.AcroFields.Fields中的var条目)
    Add(entry.Key.ToString(),string.Empty);
    reader.Close();
    返回文件;
    }
    公共字节[]填充形式(字符串pdfPath,字典formFieldMap)
    {
    var输出=新的MemoryStream();
    变量读取器=新的PDF读取器(pdfPath);
    var stamper=新的PdfStamper(读卡器,输出);
    var formFields=stamper.AcroFields;
    
    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();
    }
    
    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();