Windows机器上iText-PDF中的中文字体问题

Qoh*_*let 0 java pdf fonts itext

我正在使用Ubuntu-PC创建带有iText的PDF,部分是中文版.为了阅读它们,我使用了Evince.到目前为止几乎没有任何问题

在我的电脑上,我尝试了以下三个BaseFonts,他们成功地工作了:

bf = BaseFont.createFont("MSungStd-Light", "UniCNS-UCS2-H", BaseFont.NOT_EMBEDDED); 
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); 
bf = BaseFont.createFont("MSung-Light","UniCNS-UCS2-H", BaseFont.NOT_EMBEDDED); 
Run Code Online (Sandbox Code Playgroud)

不幸的是,在使用Acrobat-Reader在Windows上打开最终PDF时,文档无法再正确显示.

在我搜索字体以获得解决方案之后,我来到论坛,以可理解的方式解释问题(这里使用了MSung-Light):http://community.jaspersoft.com/questions/531457/chinese-font-不能待看到

您正在使用PDF中的内置中文字体.我不确定这种字体能否同时支持英文和中文,或混合语言.

使用Acrobat Reader内置字体的优点是它可以生成较小的PDF文件,因为它依赖于显示PDF的客户端计算机上可用的字体,通过预先安装的Acribat Asian Font Pack.

但是,当我们研究与内置韩文字体相关的类似问题时,使用PDF内置字体具有通过在不同机器上进行测试而发现的一些缺点.

我该怎么办呢?能够复制中文字母并不是那么重要.iText可以将段落转换为图像吗?或者有更好的解决方案吗?

Bru*_*gie 7

你正在使用CJK字体.CJK字体从不嵌入,在Adobe Reader中打开这样的文件时需要字体包.通常,Adobe Reader会询问您是否要自动安装此类字体包.如果没有,您可以在此处下载相应的字体包.

您似乎想避免让最终用户安装字体包.这在某种程度上是可以理解的.真正糟糕的是,你建议避免使用字体并逐个绘制字形.这可以用iText(并在我的书中记录),但它带有严重的警告:不要这样做!您的文件将变得臃肿,打印结果可能会非常糟糕!

另一种方法是使用另一种字体,例如arialuni.ttf,YaHei,SimHei,......这些字体包含中文字形,您可以将这些字体的子集嵌入到PDF中(嵌入整个字体会有点过分).例如,参见FontTest示例.

如果您有一个字体程序,如arialuni.ttf,您可以使用此代码创建一个BaseFont对象:

BaseFont.createFont("c:/windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Run Code Online (Sandbox Code Playgroud)

使用此字体,您可以显示在任何操作系统上使用任何查看器可见的中文字符.如果您没有arialuni.ttf,则需要查找另一种字体并使用该FontText示例来测试是否支持中文(如果在"Chinese:"之后没有看到任何文本,则不支持中文).

回复你的评论的额外答案:

请忘记iText-Asian,因为这是您想要使用CJK字体时需要的jar.您明确表示您不想使用CJK字体,因此您不需要使用iText-Asian.

如果要嵌入字体(而不是依赖字体包),则需要选择一个知道如何绘制中文字符的字体程序.这会立即引发你的问题:"你能指出一个吸引汉字的例子吗?" 无效.我可以指出你这样一个例子,但你仍然需要一个字体程序.

一旦你有了这个字体程序:你为什么不以正确的方式使用它?您应该按照您应该使用的方式使用该字体程序.您不应该使用该字体程序将您的字形绘制为图像,因为这将导致PDF文件具有巨大的文件大小和错误的分辨率(字形的质量差,因为您绘制每个单独的字符而不是使用字体程序PDF).

你找了一个字体程序吗?有关于越南字体类似的问题前一阵子:无法导出利用iText越南字符PDF我花了不到我的时间,以谷歌为可以使用的字体的四分之一.你为什么不花四分之一的时间找一个支持中文的字体?

额外答复回复您的额外评论:

  1. 当我们引用CJK时,我们指的是一种特定的方法,其中没有嵌入字体,而是依赖于最终用户机器上安装的字体包,以便Adobe Reader可以使用该字体.你不想要这个所以你所有关于使用itext亚洲jar和MSung-Light等的问题是无关紧要的.
  2. 中文字符很大,很多电脑都没有任何中文字体(特别是在美国),所以你的问题"没有办法使用内置的arialuni"的答案"不,你不应该指望那个!"
  3. 你对越南语的评价是无关紧要的.字体是字体是字体.一侧有字符代码,另一侧有字形.将一个与另一个连接的粘合剂是编码.例如:您有十六进制字符代码B2E2和十六进制字符代码CAD4.如果编码是GBK,则相应的字形是测试和试验.请注意,当您想要在UNICODE中表示相同的字符时,您将使用字符6D4D和8BD5.与其他系统几乎没有什么区别.例如:您有十六进制字符代码41(十进制数为65),如果编码为Latin-1,则相应的字形为A.
  4. 我已经要求您搜索支持中文的字体.我打开谷歌,搜索关键词"中文字体".我找到了这个页面:http://www.freechinesefont.com/我选择了一个对我来说似乎没问题的字体:http://www.freechinesefont.com/simplified-hxb-mei-xin-download/

现在我使用这段代码:

import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;

public class ChineseTest {
    /** Path to the resulting PDF file. */
    public static final String DEST = "results/test.pdf";
    /** Path to the vietnamese font. */
    public static final String FONT = "resources/hxb-meixinti.ttf";

    /**
     * Creates a PDF file: hello.pdf
     * @param    args    no arguments needed
     */
    public static void main(String[] args) throws DocumentException, IOException {
        new ChineseTest().createPdf(DEST);
    }

    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException 
     */
    public void createPdf(String filename) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        BaseFont bf = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font font = new Font(bf,15);
        // step 4
        document.add(new Paragraph("\u6d4b\u8bd5", font));
        // step 5
        document.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果在Windows上看起来像这样:

在此输入图像描述

这和越南人有什么不同?单词测试用中文正确显示.嵌入了字体的子集,这意味着您可以保持较低的文件大小.文本不是作为图像嵌入的,这意味着文本的质量非常好.

回答您的额外评论的额外答案:在您的评论中,您声称使用该文件的示例hxb-meixinti.ttf需要安装字体.那是不对的.hxb-meixinti.ttf仅仅是一个由iText读取的文件,用于将特定字形(字体的子集)的定义嵌入到PDF中.

当你写:与字体程序相关:Java似乎能够在不使用外部软件的情况下完成.Java能够使用字体,因为Java使用字体文件,就像iText使用字体文件一样.

有关详细信息,请阅读Java手册中的" 支持的字体 ".我引用:

物理字体需要安装在Java运行时环境已知的位置.JRE在两个位置查找:JRE本身内的lib/fonts目录,以及主机操作系统定义的普通字体位置.如果两个位置都存在同名字体,则使用lib/fonts目录中的字体.

我尝试解释的(以及自此线程开始以来你一直忽略的)是iText需要访问物理字体.iText可以接受来自文件或作为a的字体byte[],但你需要提供类似TTF,OTF,TTC,AFM + PFB 的字体.这与Java的工作方式没有什么不同.

在您的评论中,您还说您希望Adobe Reader接受字节流而不是从文件中读取PDF.这是不可能的.Adobe Reader始终要求在磁盘上存在PDF文件.即使PDF文件由浏览器提供服务,PDF的字节也会存储为临时文件.这是您的请求所固有的,需要在Adobe Reader中查看该文件.

你的其他评论不清楚.你是什​​么意思如果每个人都只是上传任何他可能需要切换的东西会导致困难.你在谈论下载而不是上传?另外:我给了你一个解决方案,不需要在客户端下载任何额外的东西,但你继续唠叨没有人会在Acrobat上安装任何东西.

至于你对BS的评论我最近得到了一个解决方案,我不知道BS的意思.