我有一个在 InDesign 中使用单选按钮组创建的 PDF 文档。每个选择都有其价值。
PdfFormField field = AcroForm.GetField(fieldName);
field.SetValue(valueToSet);
在 InDesign 中设置指定的选项值不起作用。不会选择任何选项。仅当我输入“0”或“1”等字符串数字时它才有效,但不是实际值。我想用选择的值来设置该值。我不想使用选择的“索引”。
field.GetAppearanceStates();
如果我返回所有状态,我可以看到所有选择值、它们的索引和关闭状态。 我究竟做错了什么?如何使用 c# iText7 为选项值分配值?谢谢。
我遇到了同样的问题。我联系了 iText 支持,这是他们的回复:
我想对 iText 的实施决定提供一些见解 字段值“V”作为单选按钮字段的字符串,相反 遵循 PDF 规范的建议。虽然 PDF 规范 建议使用数字类型作为“V”条目,我们选择 在我们的实现中使用字符串值。这种方法确保 我们更广泛的设计中的一致性和兼容性。 通过扩展 来自公共表单字段对象的所有字段,包括“V”条目 一个字符串,我们保持统一的方法。
我针对itext7/8字符串值实现方式开发的是将一组单选按钮值映射到使用GetAppearanceStates()函数返回的字符串数值的过程。
首先要做的是获取状态:
List<string> appearanceStates = pdfFormFields.GetField("some field name").GetAppearanceStates().ToList();
检查返回的状态时,您会注意到,在 PDF 表单中找到所有单选按钮组值之后,您将首先看到一个 0,然后是一个“Off”值,后面跟着 1、2 等,具体取决于单选按钮的数量在您定位的单选按钮组中。您需要从返回的列表中删除“关闭”状态:
appearanceStates.Remove("Off");
接下来,您需要将单选按钮组值从字符串数值分解为两个单独的列表。两个列表应包含相同数量的项目:
List<string> radioButtonGroupValues = appearanceStates.Take(appearanceStates.Count / 2).ToList();
List<string> numericEquivalentList = appearanceStates.Skip(appearanceStates.Count / 2).ToList();
现在创建一个 Dictionary
Dictionary<string, string> dictionary = new Dictionary<string, string>();
for (int i = 0; i < radioButtonGroupValues .Count; i++)
{
dictionary[radioButtonGroupValues [i]] = numericEquivalentList[i];
}
最后,您可以使用 linq 查询返回映射的字符串数值,其中键与您想要在 PDF 表单中设置为“On”的单选按钮值匹配:
string result = (from x in dictionary where x.Key == "radio button value" select x.Value).FirstOrDefault();
我将所有这些都放在一个类中,并将其变成了单例。无论单选按钮组中有多少个单选按钮,该类始终返回在 PDF 表单中准确选择单选按钮组中的单选按钮所需的字符串数值。我的类中某些变量的名称与上面显示的不同,但这是为了简化目的。为您自己的变量命名任何对您来说最有意义的名称。
public class ITextRadioFieldUnifier
{
private static ITextRadioFieldUnifier instance = null;
private static object syncRoot = new object();
public ITextRadioFieldUnifier() { }
public static ITextRadioFieldUnifier Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new ITextRadioFieldUnifier();
}
}
}
return instance;
}
}
internal string ReturnExtendedString(PdfAcroForm pdfFormFields, string field, string value)
{
List<string> appearanceStates = pdfFormFields.GetField(field).GetAppearanceStates().ToList();
appearanceStates.Remove("Off");
Dictionary<string, string> map = CreateDictionary(TakeListFirstHalf(appearanceStates), SkipListFirstHalf(appearanceStates));
return MapKeyValue(map, value);
}
private List<string> TakeListFirstHalf(List<string> states) => states.Take(states.Count / 2).ToList();
private List<string> SkipListFirstHalf(List<string> states) => states.Skip(states.Count / 2).ToList();
private Dictionary<string, string> CreateDictionary(List<string> valuesList, List<string> numericEquivalentList)
{
if (valuesList.Count != numericEquivalentList.Count)
{
throw new ArgumentException("Input lists must have the same number of elements.");
}
Dictionary<string, string> dictionary = new Dictionary<string, string>();
for (int i = 0; i < valuesList.Count; i++)
{
dictionary[valuesList[i]] = numericEquivalentList[i];
}
return dictionary;
}
private string MapKeyValue(Dictionary<string, string> map, string value)
{
return (from x in map where x.Key == value select x.Value).FirstOrDefault();
}
}
要使用该类,我可以在 .SetValue 中设置值时调用该函数,如下所示:
pdfFormFields.GetField("form field").SetValue(ITextRadioFieldUnifier.Instance.ReturnExtendedString(pdfFormFields, "form field", "value of your radio button"));
或者我可以像这样或类似的变体将其分解:
string result = ITextRadioFieldUnifier.Instance.ReturnExtendedString(pdfFormFields, "form field", "value of your radio button");
PdfFormField formField = pdfFormFields.GetField("form field");
formField.SetValue(result);
我确信有人可能已经开发出了更好的解决方案,但我在搜索过程中找不到任何东西。希望这对现在或将来可能处理此问题的人有所帮助。