用西里尔值填充pdf模板字段(itextsharp)

时间:2016-05-16 15:26:17

标签: c# pdf itextsharp acrobat

我有带有字段的PDF模板文件。 客户创建的模板。它有一些文本,字段标签和字段本身。文本和标签使用嵌入模板中的某种字体。

当我尝试用西里尔值填充字段时出现问题 - 结果文档中没有西里尔符号。

我看到很多类似的问题都是通过使用AcroFields的替换字体来解决的。但是在这里我不能使用一种特定字体进行替换,因为我无法在模板中定义字段字体。

我尝试为Acrobat Editor中的字段设置不同的字体 - Times New Roman,Arial和其他众所周知的Windows字体,但对结果pdf没有影响。

代码示例:

        FontFactory.RegisterDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Fonts));
        using (var dest = File.Create(@"result.pdf"))
        {
            using (var stamper = new PdfStamper(reader, dest))
            {
                var fields = stamper.AcroFields;
                fields.SetField("ClientName", "Имя клиента");
                stamper.FormFlattening = true;
                stamper.Close();
            }
        }

我甚至在FontFactory中注册了所有可用的字体,但没有效果。

所以问题是: 1.如果我可以在仅用于字段的Adobe Acrobat中嵌入字体,那么该怎么做? 2.如果我可以使用iTextSharp为现有字段定义字体系列,那么该怎么做?

1 个答案:

答案 0 :(得分:0)

好吧,我写了适合我的解决方案。

  1. 在FontFactory中注册所有现有的系统字体。
  2. 阅读文档元数据以提取文档中所有使用过的字体。
  3. 读取字段元数据并尝试创建适合字段字体的BaseFont。如果没有合适的字体 - 请使用后备字体(带编码IDENTITY_H的arial)。
  4. 所以完整代码如下:

        static IEnumerable<PdfFontInfo> ReadDocumentFonts(PdfReader reader)
        {
            if (reader.AcroForm == null)
                yield break;
            var dr = reader.AcroForm.GetAsDict(PdfName.DR);
    
            // Read font information from resources
            var fontDict = dr.GetAsDict(PdfName.FONT);
            foreach (var fontKey in fontDict.Keys)
            {
                var data = fontDict.GetAsDict(fontKey);
                // Read font descriptor if it possible
                var descriptor = data.GetAsDict(PdfName.FONTDESCRIPTOR);
                if (descriptor != null)
                {
                    // Read font name and family
                    var family = descriptor.GetAsString(PdfName.FONTFAMILY);
                    yield return new PdfFontInfo(fontKey, family.ToUnicodeString());
                }
            }
        }
    
        static IReadOnlyList<BaseFont> CreateSubstitutionFontsForFields(PdfReader reader)
        {
            if (reader.AcroForm.Fields == null)
                return new List<BaseFont>(0);
            var documentFontMap = ReadDocumentFonts(reader).ToDictionary(f => f.Name, StringComparer.InvariantCultureIgnoreCase);
            var substFonts = new Dictionary<string, BaseFont>();
            var fallbackRequired = false;
    
            // Read font information of each field
            foreach (var field in reader.AcroForm.Fields)
            {
                var fieldFontDa = field.Info.GetAsString(PdfName.DA);
                if (fieldFontDa == null)
                    continue;
                var parts = AcroFields.SplitDAelements(fieldFontDa.ToUnicodeString());
                if (parts.Length == 0)
                    continue;
                var fontName = (string) parts[0];
                PdfFontInfo inf;
                if (documentFontMap.TryGetValue(fontName, out inf))
                {
                    if (!substFonts.ContainsKey(fontName))
                    {
                        var font = FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, true).BaseFont;
                        substFonts.Add(fontName, font);
                    }
                }
                else
                    fallbackRequired = true;
            }
            var allFonts = new List<BaseFont>(substFonts.Values);
            if (fallbackRequired)
                allFonts.Add(FALLBACK_FONT);
            return allFonts;
        }
    

    如果您发现任何错误,欢迎您发表评论。