【问题标题】:Extract PDF group fields values from PDF document using IText7使用 IText7 从 PDF 文档中提取 PDF 组字段值
【发布时间】:2021-05-20 09:35:52
【问题描述】:

我需要使用 IText7 从 PDF 文档中提取 PDF 字段值。我正在提取字符串字段没有任何问题。但是当我尝试提取作为字段组成员的字段值(例如切换按钮)时,我遇到了下一个问题。 这是我的测试代码。

public class PdfTest
{
    // PDF document path
    public string PdfFilePath { get; set; } = string.Empty;

    //PDF document copy path
    public string PdfFileCopyPath { get; set; } = string.Empty;

    private PdfDocument PdfDoc { get; set; }

    public PdfTest(string pdfFilePath)
    {
        Load(pdfFilePath);
    }

    /// <summary>
    /// Create copy of PDF document
    /// </summary>
    /// <param name="pdfFilePath">PDF document path</param>
    /// <returns></returns>
    public bool CreateCopyFile(string pdfFilePath)
    {
        try
        {
            // Define directory for file copy
            string currentAssemblyPath = IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            string copyFileDirectory = string.Format("{0}\\Work\\Pdf", currentAssemblyPath);
            if (!IO.Directory.Exists(copyFileDirectory))
                IO.Directory.CreateDirectory(copyFileDirectory);

            // Copy file
            string copyFilePath = string.Format("{0}\\{1}", copyFileDirectory, IO.Path.GetFileName(pdfFilePath));

            if (IO.File.Exists(copyFilePath))
                IO.File.Delete(copyFilePath);

            IO.File.Copy(pdfFilePath, copyFilePath, true);

            PdfFileCopyPath = copyFilePath;

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    /// <summary>
    /// Load PDF document
    /// </summary>
    /// <param name="pdfFilePath">Pdf document path</param>
    /// <returns></returns>
    public bool Load(string pdfFilePath)
    {
        bool result = true;
        try
        {
            PdfFilePath = pdfFilePath;

            // Create pdf file copy
            result = result & CreateCopyFile(PdfFilePath);

            //Initialize pdf document
            PdfReader pdfReader = new PdfReader(PdfFilePath);

            WriterProperties writerProperties = new WriterProperties();
            writerProperties.AddXmpMetadata().AddXmpMetadata().SetPdfVersion(PdfVersion.PDF_1_6);
            PdfWriter pdfWriter = new PdfWriter(PdfFileCopyPath, writerProperties);
            pdfWriter.SetCompressionLevel(0);

            PdfDoc = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().UseAppendMode());

            // Get pdf fields
            IDictionary<string, PdfFormField> pdfFields = GetPdfFields();

            //Extract toggle button fields
            IDictionary<string, PdfFormField> pdfToggleButtonFields = GetPdfToggleButtonFields(pdfFields);

            //Processing toggle buttons value
            dynamic fieldValue = null;
            foreach (KeyValuePair<string, PdfFormField> field in pdfToggleButtonFields)
                fieldValue = (field.Value.GetValue() as PdfName).GetValue();

            return result;
            
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    /// <summary>
    /// Get PDF fields
    /// </summary>
    public IDictionary<string, PdfFormField> GetPdfFields()
    {
        try
        {
            // Get form fields
            PdfAcroForm pdfAcroForm = PdfAcroForm.GetAcroForm(PdfDoc, false);
            return pdfAcroForm.GetFormFields();
        }
        catch (Exception ex)
        {
            return null;
        }

    }

    /// <summary>
    /// Get toggle buttons
    /// </summary>
    public IDictionary<string, PdfFormField> GetPdfToggleButtonFields(IDictionary<string, PdfFormField> pdfFields)
    {
        Dictionary<string, PdfFormField> pdfToggleButtonsFields = new Dictionary<string, PdfFormField>();

        try
        {
            foreach (KeyValuePair<string, PdfFormField> field in pdfFields)
            {
                if ((field.Value is PdfButtonFormField) && ((field.Value as PdfButtonFormField).IsToggleOff()))
                    pdfToggleButtonsFields.Add(field.Key, field.Value);
            }

            return pdfToggleButtonsFields;

        }
        catch
        {
            return null;
        }
    }

    public bool ClosePdfFile()
    {
        try
        {
            PdfDoc.Close();
            return true;
        }
        catch
        {
            return false;
        }
    }

}

所以,使用这个类,我尝试从只有一个切换按钮组的简单 PDF 文件中加载数据。 当我使用 GetPdfToggleButtonFields 方法提取切换按钮字段时 并尝试使用构造处理切换按钮字段 fieldValue = (field.Value.GetValue() as PdfName).GetValue(),我看到字段值不是布尔值而是序数值。在我的情况下,所有按钮都是“4”。
我想这是检查的字段数。 如果切换按钮字段具有故意的逻辑名称 - 这可以。我可以分析字段名称并定义:字段所属的组和序号字段编号。 但是,如果字段具有 check1、check2、check 3 等名称,我无法定义字段所属的组和序号字段编号,因此我无法正确提取选中的按钮。

有没有人知道当字段没有刻意命名时,有什么方法可以正确定义组中字段值的逻辑值?

【问题讨论】:

    标签: c# .net pdf itext7


    【解决方案1】:

    与单选按钮相关的对象在逻辑上可以分为单选组和单选按钮。任何单选按钮都应添加到单选组中,以便与同一组中的其他单选按钮进行逻辑连接。单选按钮和单选组都是PdfButtonFormField 对象,您可以使用GetValue 方法从它们中获取价值。每个单选按钮的值是它的标识符。通常它是单选按钮的索引,但实际上可以有任何值。单选组的值是选中单选按钮的标识符。 因此,使用此信息,我们可以轻松找出当前选中了哪个单选按钮。根据您的代码,目前您似乎正在获取无线电组的值。除此之外,您还需要遍历每个组的孩子并将孩子的值与广播组中的孩子进行比较

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      相关资源
      最近更新 更多