【问题标题】:ITextSharp: Remove character Limit from a form fieldITextSharp:从表单字段中删除字符限制
【发布时间】:2012-04-18 17:55:39
【问题描述】:

我正在尝试在使用 iTextSharp 设置表单字段之前从表单字段中删除字符限制。我可以使用 Adob​​e Acrobat 手动执行此操作,但我们正在处理大量 PDF 文档,我们正在使用 iTextSharp 动态标记表单字段。我们没有构建这些 PDF 文档,我们只是将它们用作我们正在填充数据的模板。我想知道是否有一种方法可以使用 api 删除表单字段的字符限制,这样我们就不必手动检查每个字段的字符限制。

我猜这可以通过 SetFieldProperty 方法完成,但我不确定具体如何。

提前致谢

【问题讨论】:

    标签: .net c#-4.0 pdf itextsharp


    【解决方案1】:

    如果您了解 PDF 格式的内部结构,这很容易!下面的代码与code I wrote for a different type of PDF annotation here 几乎相同。该页面将更详细地解释事情并为您提供一些参考。但基本上诀窍是遍历每个页面,然后遍历每个页面的注释(表单字段属于此类),然后查找设置了最大长度的文本字段并删除该限制。所有这些工作都是在一个只读的PdfReader 对象上完成的,所以一旦我们完成了,我们需要再次循环并使用某种PdfWriter 将其写回。

    以下是针对 iTextSharp 5.2.1 的完整工作 C# 2010 WinForms 应用程序,它显示了所有这些。有关详细信息,请参阅代码中的 cmets。

    using System;
    using System.IO;
    using System.Windows.Forms;
    using iTextSharp.text;
    using iTextSharp.text.pdf;
    
    namespace WindowsFormsApplication1 {
        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e) {
                var inputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
                var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "output.pdf");
    
                //Setup some variables to be used later
                PdfDictionary PageDictionary = default(PdfDictionary);
                PdfArray Annots = default(PdfArray);
    
                //Bind a reader to our input PDF
                PdfReader R = new PdfReader(inputFile);
                //Store the number of pages
                int PageCount = R.NumberOfPages;
                //Loop through each page remember that page numbers start at 1
                for (int i = 1; i <= PageCount; i++) {
                    //Get the current page
                    PageDictionary = R.GetPageN(i);
    
                    //Get all of the annotations for the current page
                    Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);
    
                    //Make sure we have something
                    if ((Annots == null) || (Annots.Length == 0)) { continue; }
    
                    //Loop through each annotation
                    foreach (PdfObject A in Annots.ArrayList) {
                        //Convert the itext-specific object as a generic PDF object
                        PdfDictionary AnnotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(A);
    
                        //See if this annotation has a WIDGET which would be the UI implementation of a form field
                        if (!AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.WIDGET)) { continue; }
    
                        //See if this annotation is a text field (TX)
                        if (!AnnotationDictionary.Get(PdfName.FT).Equals(PdfName.TX)) { continue; }
    
                        //See if it has a maximum length specified (MAXLEN)
                        if (AnnotationDictionary.Contains(PdfName.MAXLEN)) {
                            //If so, remove it
                            AnnotationDictionary.Remove(PdfName.MAXLEN);
                        }
                    }
                }
                //Next we create a new document add import each page from the reader above
                using (FileStream FS = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
                    using (Document Doc = new Document()) {
                        using (PdfCopy writer = new PdfCopy(Doc, FS)) {
                            Doc.Open();
                            for (int i = 1; i <= R.NumberOfPages; i++) {
                                writer.AddPage(writer.GetImportedPage(R, i));
                            }
                            Doc.Close();
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 克里斯,此解决方案可能会有所帮助,但是否可以在设置字段之前更改现有字段(我知道其 ID/名称)并删除 MAXLEN 属性?目前我正在为每个需要设置的字段做类似的事情:TargetObject.SetField({FieldName}, {text for field})。 TargetObject 是一个 AcroFields 对象。
    【解决方案2】:

    我能够使用 Chris 提供的信息来解决这个问题。在设置值之前,我试图删除任何字段的任何最大长度限制。

                //TargetObject is an AcroFields object
                AcroFields.Item item = TargetObject.GetFieldItem({FieldName});
                if (item != null)
                {
                    foreach (var i in item.merged)
                    {
                        if (i.GetType() == typeof(PdfDictionary))
                        {
                            PdfDictionary dictionary = (PdfDictionary)i;
                            if (dictionary.Contains(PdfName.MAXLEN))
                            {
                                dictionary.Remove(PdfName.MAXLEN);
                            }
                            break; //no need to continue once we find the dictionary and remove max length
                        }
                    }
                }
    

    【讨论】:

    • 嗨。你的代码不起作用。没有合并的属性,有一个 GetMerged(0) 并且该字典中的项目是 KeyValuePair 对象。你介意修复代码吗?我正在尝试做同样的事情,但它似乎没有任何效果。谢谢!
    • 我的代码是这样的:AcroFields.Item item = ctx.Fields.GetFieldItem(ctx.FieldName); if (item != null) { PdfDictionary mergedFieldDictionary = item.GetMerged(0); PdfNumber maxLengthNumber = mergedFieldDictionary.GetAsNumber(PdfName.MAXLEN); if (maxLengthNumber != null) mergedFieldDictionary.Remove(PdfName.MAXLEN); } 但是当通过 PdfStamp 保存 pdf 时它没有任何效果。约束没有被移除。
    猜你喜欢
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2011-08-21
    • 2012-12-20
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多