[英]Populate PdfRadioButtonField using PDFSharp
I'm using PDFSharp version 1.50.4740-beta5 from http://www.pdfsharp.net which I installed from NuGet.我使用的是来自http://www.pdfsharp.net 的PDFSharp 1.50.4740-beta5 版本,我从 NuGet 安装了该版本。
I'm able to fill text form fields and checkbox form fields but I can't get radio buttons to work at all.我可以填写文本表单字段和复选框表单字段,但我根本无法使用单选按钮。 I don't get an error.
我没有收到错误。 SelectedIndex is -1 before and after I set it to 1.
SelectedIndex 在我将其设置为 1 之前和之后都是 -1。
Several at articles on Stack Overflow have helped me to get this far. Stack Overflow 上的几篇文章帮助我走到了这一步。 Has anyone successfully populated radio button form fields using this product?
是否有人使用此产品成功填充了单选按钮表单字段? Here is a link to the sample PDF: http://www.myblackmer.com/bluebook/interactiveform_enabled.pdf
这是示例 PDF 的链接: http : //www.myblackmer.com/bluebook/interactiveform_enabled.pdf
(Before you suggest iTextPdf, I've already evaluated it and Aspose.PDF and they are not practical) (在你推荐 iTextPdf 之前,我已经评估过它和 Aspose.PDF 并且它们不实用)
//using PdfSharp.Pdf.IO;
//using PdfSharp.Pdf;
//using PdfSharp.Pdf.AcroForms;
string fileName = "x:\\interactiveform_enabled.pdf";
PdfSharp.Pdf.PdfDocument pdfDocument = PdfReader.Open(fileName);
//The populated fields are not visible by default
if (pdfDocument.AcroForm.Elements.ContainsKey("/NeedAppearances"))
{
pdfDocument.AcroForm.Elements["/NeedAppearances"] = new PdfBoolean(true);
}
else
{
pdfDocument.AcroForm.Elements.Add("/NeedAppearances", new PdfBoolean(true));
}
PdfRadioButtonField currentField = (PdfRadioButtonField)(pdfDocument.AcroForm.Fields["Sex"]);
currentField.ReadOnly = false;
currentField.SelectedIndex = 1;
pdfDocument.Flatten();
pdfDocument.Save("x:\\interactiveform_enabled_2.pdf");
The following worked for me:以下对我有用:
Value
property with a PdfName
instance (not a PdfString
!)Value
属性与PdfName
实例(不是PdfString
!)一起使用/
before the value name/
Example, if you want to set the option "choice1" selected:例如,如果要设置选项“choice1”被选中:
var radio = (PdfRadioButtonField)form.Fields["MyRadioButtonField"];
radio.Value = new PdfName("/choice1");
I found the solution at https://forum.pdfsharp.net/viewtopic.php?f=2&t=632我在https://forum.pdfsharp.net/viewtopic.php?f=2&t=632找到了解决方案
Since this is #1 in a Google search for "PDFSharp radio buttons", figured I'd share what seems to be working for me.由于这是在 Google 搜索“PDFSharp 单选按钮”中排名第一,我想我会分享似乎对我有用的内容。
I created extension functions for the PdfRadioButtonField
object that:我为
PdfRadioButtonField
对象创建了扩展函数:
In the following examples, ErPdfRadioOption
is:在以下示例中,
ErPdfRadioOption
是:
public class ErPdfRadioOption
{
public int Index { get; set; }
public string Value { get; set; }
}
public static List<ErPdfRadioOption> FindOptions(this PdfRadioButtonField source) {
if (source == null) return null;
List<ErPdfRadioOption> options = new List<ErPdfRadioOption>();
PdfArray kids = source.Elements.GetArray("/Kids");
int i = 0;
foreach (var kid in kids) {
PdfReference kidRef = (PdfReference)kid;
PdfDictionary dict = (PdfDictionary)kidRef.Value;
PdfDictionary dict2 = dict.Elements.GetDictionary("/AP");
PdfDictionary dict3 = dict2.Elements.GetDictionary("/N");
if (dict3.Elements.Keys.Count != 2)
throw new Exception("Option dictionary should only have two values");
foreach (var key in dict3.Elements.Keys)
if (key != "/Off") { // "Off" is a reserved value that all non-selected radio options have
ErPdfRadioOption option = new ErPdfRadioOption() { Index = i, Value = key };
options.Add(option);
}
i++;
}
return options;
}
Usage用法
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
return radioField.FindOptions();
Result (JSON)结果 (JSON)
[
{
"Index": 0,
"Value": "/Choice1"
},
{
"Index": 1,
"Value": "/Choice2"
},
{
"Index": 2,
"Value": "/Choice3"
}
]
You'd think this is what the SelectedIndex
property should be for... but apparently not.您可能会认为这是
SelectedIndex
属性的用途……但显然不是。
public static void SetOptionByIndex(this PdfRadioButtonField source,int index) {
if (source == null) return;
List<ErPdfRadioOption> options = source.FindOptions();
ErPdfRadioOption selectedOption = options.Find(x => x.Index == index);
if (selectedOption == null) return; //The specified index does not exist as an option for this radio field
// https://forum.pdfsharp.net/viewtopic.php?f=2&t=3561
PdfArray kids = (PdfArray)source.Elements["/Kids"];
int j = 0;
foreach (var kid in kids) {
var kidValues = ((PdfReference)kid).Value as PdfDictionary;
//PdfRectangle rectangle = kidValues.Elements.GetRectangle(PdfAnnotation.Keys.Rect);
if (j == selectedOption.Index)
kidValues.Elements.SetValue("/AS", new PdfName(selectedOption.Value));
else
kidValues.Elements.SetValue("/AS", new PdfName("/Off"));
j++;
}
}
Note: This depends on the FindOptions() function above.注意:这取决于上面的 FindOptions() 函数。
Usage用法
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
radioField.SetOptionByIndex(index);
public static void SetOptionByValue(this PdfRadioButtonField source, string value) {
if (source == null || string.IsNullOrWhiteSpace(value)) return;
if (!value.StartsWith("/", StringComparison.OrdinalIgnoreCase)) value = "/" + value; //All values start with a '/' character
List<ErPdfRadioOption> options = source.FindOptions();
ErPdfRadioOption selectedOption = options.Find(x => x.Value == value);
if (selectedOption == null) return; //The specified index does not exist as an option for this radio field
source.SetOptionByIndex(selectedOption.Index);
}
Note: This depends on the FindOptions()
and SetOptionByIndex()
functions above.注意:这取决于上面的
FindOptions()
和SetOptionByIndex()
函数。
Based on this post in the PDFsharp forum: https://forum.pdfsharp.net/viewtopic.php?f=2&t=3561#p11386基于 PDFsharp 论坛中的这篇文章: https ://forum.pdfsharp.net/viewtopic.php ? f =2& t = 3561#p11386
Using PDFsharp version 1.50.5147使用 PDFsharp 版本 1.50.5147
Based on Chris's answer, the salient point is that you have to set the value for all options to \\Off while setting the option's value you want to the \\Choice.根据克里斯的回答,重点是您必须将所有选项的值设置为 \\Off,同时将您想要的选项值设置为 \\Choice。 To that end, you can have a simple function like:
为此,您可以拥有一个简单的功能,例如:
//sets a radio button option by setting the index and value and turning the others off
static void setRadioOption (PdfRadioButtonField field, int option, string optvalue)
{
PdfArray kids = (PdfArray)field.Elements["/Kids"];
int j = 0;
foreach (var kid in kids)
{
var kidValues = ((PdfReference)kid).Value as PdfDictionary;
if (j == option)
kidValues.Elements.SetValue("/AS", new PdfName(optvalue));
else
kidValues.Elements.SetValue("/AS", new PdfName("/Off"));
j++;
}
}
Is it me you're looking for?你要找的是我吗?
private static void SetPdfRadiobutton(PdfDocument document, string fieldname, string newvalue, int item)
{
PdfRadioButtonField field = (PdfRadioButtonField)document.AcroForm.Fields[fieldname];
PdfArray items = (PdfArray)field.Elements["/Kids"];
for (int i = 0; i < items.Elements.Count; i++)
{
PdfDictionary keys = ((PdfReference)items.Elements[i]).Value as PdfDictionary;
keys.Elements.SetValue("/AS", i == item ? new PdfName(newvalue) : new PdfName("/Off"));
}
field.ReadOnly = true;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.