问题描述
我需要使用 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 等,我无法定义字段所属的组和序号字段编号,因此,我无法正确提取哪个按钮被选中。
当字段没有故意命名时,有人知道什么方法可以正确定义组中字段值的逻辑值吗?
解决方法
与单选按钮相关的对象在逻辑上可以分为单选组和单选按钮。任何单选按钮都应添加到单选组中,以便与同一组中的其他单选按钮逻辑连接。单选按钮和单选组都是 PdfButtonFormField
对象,您可以使用 GetValue
方法从中获取值。每个单选按钮的值是它的标识符。通常它是单选按钮的索引,但实际上可以有任何值。单选组的值为选中单选按钮的标识。
因此,使用此信息,我们可以轻松找出当前选中的单选按钮。根据您的代码,目前您似乎正在获取无线电组的值。除此之外,您还需要遍历每个组的孩子并将孩子的值与无线电组的孩子的值进行比较