【问题标题】:Get the export value of a checkbox using iTextSharp使用 iTextSharp 获取复选框的导出值
【发布时间】:2011-05-28 07:55:03
【问题描述】:

我正在使用 ITextSharp 动态填写 pdf 文档上的字段。我希望能够确定复选框的“导出值”来自代码隐藏,以便确定如果应该选中该复选框,则发送给该复选框的值。我过去使用过的大多数文档对于每个复选框都有相同的导出值,但我目前使用的文档因复选框而异。我可以遍历所有文本框并使它们保持一致,但如果我可以在运行时确定这些复选框的导出值并相应地设置它们,那么将来会节省大量时间。

提前致谢!

我尝试在 C# 中实现下面的解决方案并最终得到以下代码:

 public string GetCheckBoxExportValue(AcroFields pdfDocument, string checkBoxFieldName)
    {
        AcroFields.Item item = pdfDocument.GetFieldItem(checkBoxFieldName);
        if (item.values.Count > 0)
        {
            PdfDictionary valueDict = item.GetValue(0);

            PdfDictionary appearanceDict = valueDict.GetAsDict(PdfName.AP);

            // if there's an appearance dict at all, one key will be "Off", and the other
            // will be the export value... there should only be two.
            if (appearanceDict != null)
            {


                foreach (PdfName curKey in appearanceDict.Keys)
                {
                    if (!PdfName.OFF.Equals(curKey))
                    {
                        return curKey.ToString(); // string will have a leading '/' character
                    }
                }
            }

            // if that doesn't work, there might be an /AS key, whose value is a name with 
            // the export value, again with a leading '/'
            PdfName curVal = valueDict.GetAsName(PdfName.AS);
            if (curVal != null)
            {
                return curVal.ToString();
            }

        }
        //return null if you get this far
            return null;

    }

这只是每次都返回“/D”。我不确定 C# 中的方法是否需要有所不同,或者我只是遗漏了一些东西。

【问题讨论】:

  • @Lorenzo - 我认为你需要停止关心其他人如何使用该网站
  • @Lorenzo,我不确定我应该在常见问题解答中阅读什么内容?
  • 这是常见问题解答的摘录,用于解释如何接受答案:[...] This lets other people know that you have received a good answer to your question. Doing this is helpful because it shows other people that you're getting value from the community. (If you don't do this, people will often politely ask you to go back and accept answers for more of your questions!)

标签: c# asp.net pdf itextsharp


【解决方案1】:

好的,您需要检查低级 PDF 对象以获取适当的值。您可以在PDF Reference 中查找所述值(第 12 章:交互功能,第 7 节:交互表单)。

特别是(在 Java 中):

AcroFields.Item item = acroFields.getFieldItem(fldName);
PdfDictionary valueDict = item.getValue(0);

PdfDictionary appearanceDict = valueDict .getAsDict(PdfName.AP);

if (appearanceDict != null) {
  PdfDictionary normalAppearances = appearanceDict.getAsDict(PdfName.N);
  // /D is for the "down" appearances.

  // if there are normal appearances, one key will be "Off", and the other
  // will be the export value... there should only be two.
  if (normalAppearances != null) {
    Set<PdfName> keys = normalAppearances .getKeys();
    for (PdfName curKey : keys) {
      if (!PdfName.OFF.equals(curKey)) {
        return curKey.toString(); // string will have a leading '/' character
      }
    }
  }


}
// if that doesn't work, there might be an /AS key, whose value is a name with 
// the export value, again with a leading '/'
PdfName curVal = valueDict.getAsName(PdfName.AS);
if (curVal != null) {
  return curVal.toString();
}

类似的东西。通常的“我刚刚在此处的编辑框中写了这个”条款适用,但这应该很好。我编写了大量令人痛苦的低级 iText 代码。

【讨论】:

  • 马克 - 我很欣赏你在“iText 问题”列表中的 iText 专业知识,我很高兴你在 SO 上分享了其中的一些内容。
  • 谢谢马克,这看起来正是我想要的。
  • 我尝试实现这一点,最终得到了上面的代码。出于某种原因,这种方法对我不起作用。有什么想法吗?
  • 我每次都得到“/D”作为导出值。 AppearanceDict.Keys 中的第一个 curKey 总是以 != 形式返回到 PdfName.OFF 并且总是“/D”。有什么想法吗?
  • 标记代码效果很好,除非多个复选框与一个字段名称相关联。在 C# 中,我使用 acroFields.GetAppearanceStates(fldName) 来获取可能值的字符串数组。
【解决方案2】:

我发现设置复选框的最佳方法是:

    void SetCB(AcroFields fields, string F)
    {
        try
        {
            fields.SetField(F, fields.GetFieldItem(F).GetValue(0).GetAsDict(PdfName.AP).GetAsDict(PdfName.N).Keys.Single().ToString().TrimStart('/'));
        } catch { }
    }

错误: 序列包含多个元素

例如:

       PdfReader reader = new PdfReader("c:\\qqq\\fl100Y2.pdf");// formFile);
        using (PdfStamper stamper = new PdfStamper(reader, new FileStream("c:\\qqq\\fl100Ynew.pdf", FileMode.Create)))
        {
            AcroFields fields = stamper.AcroFields;

            bool set = fields.SetFieldProperty("FillText156", "textsize", 10.0f, null);
            SetCB(fields, "CheckBox24");
            SetCB(fields, "CheckBox24by");
             fields.SetField("FillText156", "John Doe");
            // flatten form fields and close document
            stamper.FormFlattening = true;
            stamper.Close();
        }

【讨论】:

【解决方案3】:

这是我在其他方法的基础上使用的最后一种方法:

    public string GetCheckBoxExportValue(AcroFields fields, string cbFieldName)
    {
        AcroFields.Item item = fields.GetFieldItem(cbFieldName);
        if (item.values.Count > 0)
        {
            PdfDictionary valueDict = item.values[0] as PdfDictionary;
            PdfDictionary appDict = valueDict.GetAsDict(PdfName.AP);

            if (appDict != null)
            {
                PdfDictionary normalApp = appDict.GetAsDict(PdfName.N);

                foreach (PdfName curKey in normalApp.Keys)
                {
                    if (!PdfName.OFF.Equals(curKey))
                    {
                        // string will have a leading '/' character
                        return curKey.ToString(); 
                    }
                }
            }

            PdfName curVal = valueDict.GetAsName(PdfName.AS);
            if (curVal != null)
            {
                return curVal.ToString();
            }

        }

        return null;
    }

【讨论】:

    【解决方案4】:

    我无法让 Mark 为我工作,因为 appearanceDict 始终为空。这是我编写的一种方法,适用于我正在处理的表单上的 CheckBox 和 RadioButton 控件。

    private static string GetAnswerValue(AcroFields.Item f, int i)
    {
        var widg = f.GetWidget(i);
        if (widg == null)
            return null;
        var ap = widg.GetAsDict(PdfName.AP);
        if (ap == null)
            return null;
    
        //PdfName.D also seems to work
        var d = ap.GetAsDict(PdfName.N);
        if (d == null)
            return null;
        var e = d.Keys.FirstOrDefault(n => !n.Equals(PdfName.OFF));
        if (e == null)
            return null;
        return e.ToString().Substring(1);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 2012-12-20
      • 2012-07-02
      • 2013-11-11
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多