iTextSharp国际文本

时间:2009-11-13 07:50:58

标签: c# asp.net itextsharp export-to-pdf

我在asp.net页面有一个表,并尝试将其导出为PDF文件,我有几个国际字符未在生成的PDF文件中显示,任何建议,

提前致谢

4 个答案:

答案 0 :(得分:16)

正确显示备用字符集(俄语,中文,日语等)的关键是在创建BaseFont时使用IDENTITY_H编码。

Dim bfR As iTextSharp.text.pdf.BaseFont
  bfR = iTextSharp.text.pdf.BaseFont.CreateFont("MyFavoriteFont.ttf", iTextSharp.text.pdf.BaseFont.IDENTITY_H, iTextSharp.text.pdf.BaseFont.EMBEDDED)

IDENTITY_H为您选择的字体提供unicode支持,因此您应该能够显示几乎任何字符。我把它用于俄语,希腊语和所有不同的欧洲语言字母。

编辑 - 2013年5月28日

这也适用于iTextSharp的v5.0.2。

编辑 - 2015年6月23日

下面给出了一个完整的代码示例(在C#中):

private void CreatePdf()
{
  string testText = "đĔĐěÇøç";
  string tmpFile = @"C:\test.pdf";
  string myFont = @"C:\<<valid path to the font you want>>\verdana.ttf";
  iTextSharp.text.Rectangle pgeSize = new iTextSharp.text.Rectangle(595, 792);
  iTextSharp.text.Document doc = new iTextSharp.text.Document(pgeSize, 10, 10, 10, 10);
  iTextSharp.text.pdf.PdfWriter wrtr;
  wrtr = iTextSharp.text.pdf.PdfWriter.GetInstance(doc,
      new System.IO.FileStream(tmpFile, System.IO.FileMode.Create));
  doc.Open();
  doc.NewPage();
  iTextSharp.text.pdf.BaseFont bfR;
  bfR = iTextSharp.text.pdf.BaseFont.CreateFont(myFont,
    iTextSharp.text.pdf.BaseFont.IDENTITY_H,
    iTextSharp.text.pdf.BaseFont.EMBEDDED);

  iTextSharp.text.BaseColor clrBlack = 
      new iTextSharp.text.BaseColor(0, 0, 0);
  iTextSharp.text.Font fntHead =
      new iTextSharp.text.Font(bfR, 12, iTextSharp.text.Font.NORMAL, clrBlack);

  iTextSharp.text.Paragraph pgr = 
      new iTextSharp.text.Paragraph(testText, fntHead);
  doc.Add(pgr);
  doc.Close();
}

这是创建的pdf文件的屏幕截图:

sample pdf

要记住的重要一点是,如果您选择的字体不支持您尝试发送到pdf文件的字符,那么您在iTextSharp中所做的任何事情都不会改变它。 Verdana很好地显示了我所知道的所有欧洲字体中的字符。 其他字体可能无法显示任意数量的字符。

答案 1 :(得分:5)

不呈现字符有两个可能的原因:

  1. 编码。正如Stewbob指出的那样,Identity-H是完全避免这个问题的好方法,尽管它确实要求你嵌入字体的一个子集。这有两个后果。
    1. 与未嵌入的字体相比,它增加了一些文件大小。
    2. 该字体必须获得嵌入式子集的许可。大多数是,有些不是。
  2. 字体必须包含该字符。如果你用西里尔语(俄语)字体要求一些阿拉伯语连字,那么它很可能会存在。很少有字体涵盖各种语言,而且它们往往是巨大的。我遇到的最大/最全面的字体是“Arial Unicode MS”。超过23兆字节。
  3. 这是要求嵌入SUBSETS的另一个好理由。由于你想添加几个中国字形,所以只需要几兆字节就可以了。它有点陡峭。

    如果你感到偏执,你可以使用myBaseFont.charExists(someChar)检查你的字符串是否与给定的BaseFont实例(我相信也考虑了编码)。如果你有自信的字体,我不会打扰。

    PS:Identity-H需要嵌入式子集的另一个好理由。 Identity-H从内容流中读取字节作为字形索引。字形的顺序可以从一种字体到下一种字体,甚至在相同字体的版本之间变化很大。依靠观众系统来获得完全相同的字体是一个坏主意,所以它是非法的...特别是当Acrobat / Reader开始替换字体时,因为它找不到你要求的确切字体而你没有嵌入它。

答案 2 :(得分:0)

您可以尝试设置正在使用的字体的编码。在Java中会是这样的:

BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);

其中BaseFont.CP1252是编码。尝试搜索要显示的字符所需的确切编码。

答案 3 :(得分:0)

它由默认的iTextSharp字体 - Helvetica引起 - 不支持基本字符以外(或不支持所有其他字符。

实际上有两种选择:

  1. 一种是手动将表内容重写到代码中。这种方法可能看起来更快,但它需要在代码中重复对原始表的任何修改(打破DRY原则)。在这种情况下,您可以根据需要轻松设置字体。
  2. 另一种是从HtmlEngine中提取的HTML中提取PDF。这可能听起来有点复杂和复杂(并且确实如此),但是,工作解决方案更灵活,更通用。我刚刚在一段时间内遇到了与特殊角色的斗争,并决定在stackoverflow上发布其他类似解决方案的完整解决方案:https://stackoverflow.com/a/24587745/1138663