ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – PDFBox API:如何更改字体以处理AcroForm字段中的西里尔文值

2019-09-29 21:03:21  阅读:671  来源: 互联网

标签:acrofields java fonts pdfbox field


我需要帮助使用PDFBox API将Cyrillic值添加到字段中.这是我到目前为止:

PDDocument document = PDDocument.load(file);
PDDocumentCatalog dc = document.getDocumentCatalog();
PDAcroForm acroForm = dc.getAcroForm();
PDField naziv = acroForm.getField("naziv");
naziv.setValue("Наслов"); // this part right here
naziv.setValue("Naslov"); // it works like this

当我的输入是拉丁字母时,它完美的工作.但我也需要处理西里尔语输入.
我该怎么做?

附:这是我得到的例外:
引起:java.lang.IllegalArgumentException:U 043D(‘afii10079’)在此字体中不可用Helvetica编码:WinAnsiEncoding

解决方法:

下面的代码在acroform默认资源字典中添加了适当的字体,并替换了默认外观中的名称.调用setValue()时,PDFBox使用新字体重新创建字段的外观流.

public static void main(String[] args) throws IOException
{
    PDDocument doc = PDDocument.load(new File("ZPe.pdf"));
    PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
    PDResources dr = acroForm.getDefaultResources();

    // Important: the font is Type0 (allows more than 256 glyphs) and NOT SUBSETTED
    PDFont font = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/arial.ttf"), false);

    COSName fontName = dr.add(font);
    Iterator<PDField> it = acroForm.getFieldIterator();
    while (it.hasNext())
    {
        PDField field = it.next();
        if (field instanceof PDTextField)
        {
            PDTextField textField = (PDTextField) field;
            String da = textField.getDefaultAppearance();

            // replace font name in default appearance string
            Pattern pattern = Pattern.compile("\\/(\\w+)\\s.*");
            Matcher matcher = pattern.matcher(da);
            if (!matcher.find() || matcher.groupCount() < 2)
            {
                // oh-oh
            }
            String oldFontName = matcher.group(1);
            da = da.replaceFirst(oldFontName, fontName.getName());

            textField.setDefaultAppearance(da);
        }
    }
    acroForm.getField("name1").setValue("Наслов");
    doc.save("result.pdf");
    doc.close();
}

更新4.4.2019:为了节省一些空间,在调用setValue之前删除外观可能很有用:

acroForm.getField("name1").getWidgets().get(0).setAppearance(null);

检查AcroForm默认资源中是否有未使用的字体,请参阅this answer.

更新7.4.2019:如果字体非常大(例如ArialUni)并且要设置许多字段(PDFBOX-4508),则可能会遇到性能不佳的情况.在这种情况下,请在调用setValue之前保存并重新加载文件.

要确定字体是否支持预期文本,请调用PDFont.encode()并检查IllegalArgumentException.

标签:acrofields,java,fonts,pdfbox,field
来源: https://codeday.me/bug/20190929/1833034.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有