java - Windows计算机上的iText-PDF中的中文字体问题

标签 java pdf fonts itext

我正在使用Ubuntu-PC用iText创建PDF(部分中文)。要阅读它们,我使用Evince。到目前为止,几乎没有任何问题

在我的PC上,我尝试了以下三个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); 


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

在我搜索了Fonts以获取解决方案之后,我来到了该论坛,该问题以易于理解的方式进行了解释(此处使用了MSung-Light):http://community.jaspersoft.com/questions/531457/chinese-font-cannot-be-seen


  您正在使用PDF中的内置中文字体。我不确定
  该字体同时支持英语和中文的能力,或混合使用
  反正语言。
  
  使用Acrobat Reader内置字体的优点是它
  产生较小的PDF文件,因为它依赖于那些字体
  可以在显示PDF的客户端计算机上通过
  预装的Acribat Asian Font Pack。
  
  但是,使用PDF内置字体有一些缺点,这些缺点是
  通过调查在不同的机器上发现
  与内置韩文字体有关的类似问题。


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

最佳答案

您正在使用CJK字体。 CJK字体从不嵌入,并且在Adobe Reader中打开此类文件时需要使用字体包。通常,Adobe Reader会询问您是否要自动安装这样的字体包。如果不是,则可以下载适当的字体包here

看来您要避免让最终用户安装字体包。在某种程度上是可以理解的。真正糟糕的是,您的建议是避免使用字体,而是逐个绘制字形。使用iText(在我的书中有记录)是可以实现的,但是它带有严重警告:请勿这样做!您的文件将肿,打印结果可能会很糟糕!

一种替代方法是使用另一种字体,例如arialuni.ttf,YaHei,SimHei ......这些字体包含中文标志符号,您可以将这些字体的子集嵌入到PDF中(嵌入整个字体会过大)。例如,参见FontTest示例。

如果您拥有诸如arialuni.ttf之类的字体程序,则可以使用以下代码创建BaseFont对象:

BaseFont.createFont("c:/windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);


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

回答您的评论的其他答案:

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

如果要嵌入字体(而不是依赖字体包),则需要选择一个知道如何绘制汉字的字体程序。这立即引起您关于“您能指出一个绘制汉字的例子吗?”的问题。虚空。我可以指出一个这样的例子,但是您仍然需要一个字体程序。

一旦有了该字体程序:为什么不正确使用它?您应该以应该使用的方式使用该字体程序。您不应该使用该字体程序将字形绘制为图像,因为那样会导致PDF文件的文件大小大且分辨率差(字形质量差,因为您绘制每个单独的字符而不是在字体中使用字体程序) PDF)。

您是否正在寻找字体程序?不久前,关于越南字体也有一个类似的问题:Can't export Vietnamese characters to PDF using iText我花了不到四分之一的时间去Google寻求可以使用的字体。您为什么不花四分之一的时间来查找支持中文的字体?

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


当我们提到CJK时,我们指的是不嵌入字体的特定方法,而是依靠最终用户机器上安装的字体包,以便Adobe Reader可以使用该字体。您不希望这样做,因此有关使用itext亚洲罐子和MSung-Light等的所有问题都是无关紧要的。
中文字符集很大,许多计算机出厂时都没有任何中文字体(尤其是在美国),因此,对“是否有办法使用内置arialuni的问题”的回答是“不,您不应该使用指望那个!”
您所说的越南语无关紧要。字体就是字体。一侧有一个字符代码,另一侧有一个字形。相互联系的纽带是编码。例如:您有一个十六进制字符代码B2E2和一个十六进制字符代码CAD4。如果编码为GBK,则对应的字形为测和试。请注意,当您要在UNICODE中表示完全相同的字符时,可以使用字符6D4D和8BD5。与其他系统几乎没有区别。例如:您具有十六进制字符代码41(十进制为65),并且如果编码为Latin-1,则对应的字形为A。
我已要求您搜索支持中文的字体。我已经打开Goog​​le,并搜索了“中国字体”关键字。我找到此页面: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();
    }
}


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



这和越南有什么不同?单词test正确显示为中文。字体的子集被嵌入,这意味着您可以保持较小的文件大小。文本未嵌入为图像,这意味着文本的质量非常好。

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

当您编写时:与字体程序有关:Java似乎可以在不使用外部软件的情况下做到这一点。 Java之所以能够使用字体,是因为Java使用字体文件,就像iText使用字体文件一样。

有关更多信息,请阅读Java手册中的Supported Fonts。我引用:


  物理字体需要安装在Java已知的位置
  运行环境。 JRE在两个位置查找:lib / fonts
  JRE本身中的目录和常规字体位置
  由主机操作系统定义。如果字体名称相同
  在两个位置都存在,则使用lib / fonts目录中的一个。


我试图解释的内容(以及从该线程开始以来您一直在忽略的内容)是iText需要访问物理字体。 iText可以接受文件中的字体或作为byte[]的字体,但是您需要提供诸如TTF,OTF,TTC,AFM + PFB之类的字体。这与Java的工作方式没有什么不同。

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

您的其余评论不清楚。您的意思是,如果每个人都只是上传任何内容,那么他​​可能需要切换会造成麻烦。您是在谈论下载而不是上传吗?另外:我给您提供了一个解决方案,不需要在客户端上下载任何额外的内容,但是您一直在烦恼,没人会在Acrobat上安装任何东西。

至于您对BS的评论,我最近有一个解决方案,我不知道您对BS是什么意思。

关于java - Windows计算机上的iText-PDF中的中文字体问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23958538/

相关文章:

java - SQLJ VS JAVA 文件

java - 扩展抽象类后的方法

pdf - 在哪里可以找到 XFA 规范或 DTD/架构?

css - 使用 JavaFX 8 和 CSS,某些字体不会加载,而其他字体会加载

java - 我们可以检查密码字段中的文本是否显示为屏蔽吗?

java - 使 java.util.Timer 成为守护进程的正确方法

c# - 使用 iTextsharp.dll 生成 PDF 时不应用 CSS

c++ - zLib inflate 在某些情况下结果为空

iphone - 为什么 Wingdings 在 iOS 5 上无法运行?为什么我无法在 iPhone 应用程序中使用 Wingdings?

javascript - 密码字段问题