Get the export value of a checkbox using iTextSharp

后端 未结 4 723
南笙
南笙 2020-12-10 15:57

I\'m working on dynamically filling in the fields on a pdf document using ITextSharp. I\'d like to be able to determine the \"export value\" of the checkbox is from the cod

相关标签:
4条回答
  • 2020-12-10 16:12

    I couldn't get the answer Mark to work for me because the appearanceDict was always null. Here is a method I wrote that works for the CheckBox and RadioButton controls on the forms I'm dealing with.

    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);
    }
    
    0 讨论(0)
  • 2020-12-10 16:22

    Okay, you need to check the low-level PDF objects for the appropriate values. You can look up said values in the PDF Reference (chapter 12: Interactive Features, section 7: Interactive Forms).

    In particular (and in 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();
    }
    

    Something like that. The usual "I just wrote this in the edit box here" provisions apply, but that should be good to go. I write a distressingly large amount of low level iText code.

    0 讨论(0)
  • 2020-12-10 16:23

    The best way I found to set a checkbox is:

        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 { }
        }
    

    error: Sequence contains more than one element

    e.g:

           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();
            }
    
    0 讨论(0)
  • 2020-12-10 16:23

    This was the final method I used to get it working based on the others:

        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;
        }
    
    0 讨论(0)
提交回复
热议问题