使用iText7设置PDF下拉框值时出现奇怪字符(C#)
问题
使用iText7程序化导出数据到PDF时,文本框、文本域、复选框功能正常,但设置下拉框(combobox)值时出现异常。下拉框选项为:Critique; Important; Modéré; Faible;
测试用Program.cs代码如下:
using iText.Forms; using iText.Forms.Fields; using iText.Kernel.Pdf; public class Program { public static readonly string CHECKED_STATE_VALUE = "Yes"; public static readonly string UNCHECKED_STATE_VALUE = "Off"; private static void ConsoleOutFieldData(PdfFormField field) { Console.WriteLine(field.GetFieldName() + ": " + field.GetValue()); } private static void Main(string[] args) { PdfReader reader = new PdfReader(@"C:\code-test\CERTAQ-FORM-17-001-Declaration_d_incident.pdf"); PdfWriter writer = new PdfWriter(@"C:\code-test\test1.pdf"); PdfDocument pdfDoc = new PdfDocument(reader, writer); PdfAcroForm? form = PdfAcroForm.GetAcroForm(pdfDoc, true); var fields = form.GetFormFields(); Console.WriteLine("Before :"); ConsoleOutFieldData(form.GetField("cbImpactA")); ConsoleOutFieldData(form.GetField("cbImpactB")); ConsoleOutFieldData(form.GetField("cbImpactC")); ConsoleOutFieldData(form.GetField("cbImpactD")); // Combobox form.GetField("cbImpactA").SetValue("Critique"); form.GetField("cbImpactB").SetValue("Modéré"); form.GetField("cbImpactC").SetValue("Important"); form.GetField("cbImpactD").SetValue("Faible"); Console.WriteLine("After :"); ConsoleOutFieldData(form.GetField("cbImpactA")); ConsoleOutFieldData(form.GetField("cbImpactB")); ConsoleOutFieldData(form.GetField("cbImpactC")); ConsoleOutFieldData(form.GetField("cbImpactD")); // Rendre les champs non modifiables. form.FlattenFields(); pdfDoc.Close(); } }
控制台输出及PDF显示异常:
Before : cbImpactA: Modéré cbImpactB: Critique cbImpactC: Faible cbImpactD: Important After : cbImpactA: þÿCritique cbImpactB: þÿModéré cbImpactC: þÿImportant cbImpactD: þÿFaible
PDF中的下拉框值还额外带有换行符。
解决方案
问题根源
þÿ是UTF-16LE的字节顺序标记(BOM),说明原PDF下拉框字段的值存储编码为UTF-16。直接调用SetValue(string)时,iText7默认按UTF-8处理字符串,导致编码不匹配,额外插入了BOM字符;PDF中的换行符大概率是原表单选项定义时自带的,或编码转换过程中引入的。
修复步骤
匹配字段的UTF-16编码
改用SetValue(byte[])重载方法,将字符串转换为UTF-16LE编码的字节数组传入:// 替换原SetValue代码块 var unicodeEncoding = System.Text.Encoding.Unicode; // .NET中对应UTF-16LE form.GetField("cbImpactA").SetValue(unicodeEncoding.GetBytes("Critique")); form.GetField("cbImpactB").SetValue(unicodeEncoding.GetBytes("Modéré")); form.GetField("cbImpactC").SetValue(unicodeEncoding.GetBytes("Important")); form.GetField("cbImpactD").SetValue(unicodeEncoding.GetBytes("Faible"));清除多余换行符
如果PDF中仍存在换行,可先去除字符串中的换行符再转换编码:string cleanValue = "Critique".Trim().Replace("\r", "").Replace("\n", ""); form.GetField("cbImpactA").SetValue(unicodeEncoding.GetBytes(cleanValue));确认字段编码(可选)
若不确定字段编码,可通过GetValueAsString(PdfDocument)方法获取原始值的编码信息,或检查原PDF表单的字段属性,确认值的存储编码类型。
内容的提问来源于stack exchange,提问作者Maxime Baker
相关产品推荐
相关产品推荐

