【问题标题】:Html to pdf some characters are missing (itextsharp)Html 到 pdf 缺少一些字符(itextsharp)
【发布时间】:2010-11-22 06:42:33
【问题描述】:

我想使用 itextsharp 库将 gridview 导出为 pdf。问题是 pdf 文档中缺少一些土耳其语字符,例如 İ,ı,Ş,ş 等。用于导出pdf的代码是:

 protected void LinkButtonPdf_Click(object sender, EventArgs e)
    {
        Response.ContentType = "application/pdf";
        Response.ContentEncoding = System.Text.Encoding.UTF8;
        Response.AddHeader("content-disposition", "attachment;filename=FileName.pdf");
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        System.IO.StringWriter stringWrite = new StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
        GridView1.RenderControl(htmlWrite);
        StringReader reader = new StringReader(textConvert(stringWrite.ToString()));
        Document doc = new Document(PageSize.A4);
        HTMLWorker parser = new HTMLWorker(doc);
        PdfWriter.GetInstance(doc, Response.OutputStream);
        doc.Open();
        parser.Parse(reader);
        doc.Close();
    }
    public static string textConvert(string S)
    {
        if (S == null) { return null; }
        try
        {
            System.Text.Encoding encFrom = System.Text.Encoding.UTF8;
            System.Text.Encoding encTo = System.Text.Encoding.UTF8;
            string str = S;
            Byte[] b = encFrom.GetBytes(str);
            return encTo.GetString(b);
        }
        catch { return null; }
    }

注意:当我想在 pdf 文档中插入字符时,缺少的字符会显示在其中。我用这个代码插入字符:

   BaseFont bffont = BaseFont.CreateFont("C:\\WINDOWS\\Fonts\\arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        Font fontozel = new Font(bffont, 12, Font.NORMAL, new Color(0, 0, 0));
        doc.Add(new Paragraph("İİııŞŞşşĞĞğğ", fontozel));

【问题讨论】:

    标签: c# .net asp.net pdf-generation itextsharp


    【解决方案1】:

    我不熟悉 iTextSharp 库;但是,您似乎正在将 gridview 组件的输出转换为字符串并从该字符串中读取以构建您的 PDF 文档。您还进行了从 UTF-8 到 UTF-8 的奇怪转换。

    据我所见(假设您的 GridView 正确输出字符),如果您将字符输出到字符串,它们将在内存中表示为 UTF-16。您可能需要将此字符串直接传递到 PDF 库中(就像您传递原始 UTF-16 .NET 字符串 "İııŞŞşşĞĞğğ" 一样)。

    【讨论】:

    • 抱歉 UTF-8 到 UTF-8 的转换,这只是试用,我在写问题时忘记了这样的问题。我尝试了不同的组合,例如 UTF-8 到 Unicode,Unicode 到 UTF-8 等...
    • 我想说的是:如果你不做任何转换会发生什么?
    • 没有转换,字符仍然丢失。
    【解决方案2】:

    土耳其语编码

    CultureInfo ci = new CultureInfo("tr-TR");
    Encoding enc = Encoding.GetEncoding(ci.TextInfo.ANSICodePage);
    

    如果您要输出 HTML,请在页面顶部尝试不同的 DOCTYPE 标签。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    

    注意如果使用 HTML,您可能需要对字符进行 HTMLEncode。

    Server.HTMLEncode()

    HttpServerUtility.HtmlEncode()

    【讨论】:

    • 我按照你说的做了,但没有任何改变。我认为我们必须更改 htmlworker 的字体,但不知道如何更改。谢谢
    【解决方案3】:

    最后我想我找到了解决方案,我稍微更改了 itextsharp 源代码以显示土耳其字符。(土耳其字符代码是 cp1254)

    我在源代码的[BaseFont.cs]中添加了“public const string CP1254 = "Cp1254";”。

    之后我修改了[FactoryProperties.cs]。我改成这样了;

    public Font GetFont(ChainedProperties props)
    {
    I don't write the whole code.I changed only code below;
    ------------Default itextsharp code------------------------------------------------------
      if (encoding == null)
                    encoding = BaseFont.WINANSI;
                return fontImp.GetFont(face, encoding, true, size, style, color);
    -------------modified code--------------------------------------------
    
                encoding = BaseFont.CP1254;
                return fontImp.GetFont("C:\\WINDOWS\\Fonts\\arial.ttf", encoding, true, size, style, color);
    }
    

    。在我编译新的 dll 后,会显示缺少的字符。

    【讨论】:

    • 这非常有效。尤其是在将 gridview 导出为 pdf 时。非常感谢。
    • 谢谢。它在开始时不起作用。除了你,我搜索整个项目并更改所有“BaseFont.WINANSI”->“BaseFont.CP1254”。然后它就完美运行了。
    【解决方案4】:

    无需更改源代码。

    试试这个:

    iTextSharp.text.pdf.BaseFont STF_Helvetica_Turkish = iTextSharp.text.pdf.BaseFont.CreateFont("Helvetica","Cp1254", iTextSharp.text.pdf.BaseFont.NOT_EMBEDDED);    
    
    iTextSharp.text.Font fontNormal = new iTextSharp.text.Font(STF_Helvetica_Turkish, 12, iTextSharp.text.Font.NORMAL);
    

    【讨论】:

    • @Jason Plank 这个字体可以分配给 LoadTagStyle 中的 html 标签正文吗?
    • 这应该是答案! var font1 = FontFactory.GetFont(BaseFont.HELVETICA, "Cp1254", BaseFont.NOT_EMBEDDED, 24, Font.BOLD, BaseColor.BLACK);
    【解决方案5】:
    BaseFont bF = BaseFont.CreateFont("c:\\arial.ttf","windows-1254",true);
    Font f = new Font(bF,12f,Font.NORMAL);
    Chunk c = new Chunk();
    c.Font = f;
    c.Append("Turkish characters: ĞÜŞİÖÇ ğüşıöç");
    document.Add(c);
    

    在第一行,你可以写这些而不是“windows-1254”。所有作品:

    • CP1254
    • iso-8859-9
    • windows-1254

    【讨论】:

      【解决方案6】:

      你可以使用:

      iTextSharp.text.pdf.BaseFont Vn_Helvetica = iTextSharp.text.pdf.BaseFont.CreateFont(@"C:\Windows\Fonts\arial.ttf", "Identity-H", iTextSharp.text.pdf.BaseFont.EMBEDDED);
      iTextSharp.text.Font fontNormal = new iTextSharp.text.Font(Vn_Helvetica, 12, iTextSharp.text.Font.NORMAL);
      

      【讨论】:

      • @Jason Plank 这个字体可以分配给 LoadTagStyle 中的 html 标签正文吗?
      • @Alex 我不知道,我只修复了这个答案的格式。不幸的是,这个答案的作者似乎不再在这里活跃了。
      【解决方案7】:

      我解决了这个问题。我可以提供我的其他解决方案类型...

      try
      {
              BaseFont bf = BaseFont.CreateFont("c:\\windows\\fonts\\calibrib.ttf",
                  BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
              Document document = new Document(PageSize.A4, 25, 25, 30, 30);
              PdfWriter writer = PdfWriter.GetInstance(document, fs);
      
              Font f = new Font(bf, 12f, Font.NORMAL);
              // Open the document to enable you to write to the document
              document.Open();
              // Add a simple and wellknown phrase to the document
              for (int x = 0; x != 100; x++)
              {
                  document.Add(new Paragraph("Paragraph - This is a test! ÇçĞğİıÖöŞşÜü",f));
              }
      
              // Close the document
              document.Close();          
      }
      catch(Exception)
      {
      
      }
      

      【讨论】:

        【解决方案8】:

        不要更改 iTextSharp 的源代码。定义新样式:

                var styles = new StyleSheet();
                styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.FONTFAMILY, "tahoma");
                styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, "Identity-H");
        

        然后将其传递给 HTMLWorker.ParseToList 方法。

        【讨论】:

          【解决方案9】:

          我终于找到了解决这个问题的方法,通过这个你可以打印所有土耳其字符。

          String htmlText = html.ToString();

              Document document = new Document();
          
              string filePath = HostingEnvironment.MapPath("~/Content/Pdf/");
              PdfWriter.GetInstance(document, new FileStream(filePath + "\\pdf-"+Name+".pdf", FileMode.Create));
              document.Open();
          
              iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(document);
              FontFactory.Register(Path.Combine(_webHelper.MapPath("~/App_Data/Pdf/arial.ttf")),  "Garamond");   // just give a path of arial.ttf 
              StyleSheet css = new StyleSheet();
              css.LoadTagStyle("body", "face", "Garamond");
              css.LoadTagStyle("body", "encoding", "Identity-H");
              css.LoadTagStyle("body", "size", "12pt");
          
              hw.SetStyleSheet(css);
          
               hw.Parse(new StringReader(htmlText));
          

          【讨论】:

            【解决方案10】:

            非常感谢所有发布示例的人..

            我使用 codeproject 的以下解决方案,由于字体存在土耳其字符集问题..

            如果你使用 htmlworker 你应该注册字体并传递给 htmlworker

            http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3

                  StyleSheet styles = new iTextSharp.text.html.simpleparser.StyleSheet();
                            styles.LoadTagStyle("h3", "size", "5");
                            styles.LoadTagStyle("td", "size", ".6");
                            FontFactory.Register("c:\\windows\\fonts\\arial.ttf", "Garamond");   // just give a path of arial.ttf 
                            styles.LoadTagStyle("body", "face", "Garamond");
                            styles.LoadTagStyle("body", "encoding", "Identity-H");
                            styles.LoadTagStyle("body", "size", "12pt");
                            using (var htmlViewReader = new StringReader(htmlText))
                            {
                                using (var htmlWorker = new HTMLWorker(pdfDocument, null, styles))
                                {
                                    htmlWorker.Parse(htmlViewReader);
                                }
                            }
            

            【讨论】:

              【解决方案11】:

              我强烈建议不要为了解决这个问题而更改 itextsharp 源代码。看看我对这个主题的其他评论:https://stackoverflow.com/a/24587745/1138663

              【讨论】:

                猜你喜欢
                • 2014-02-19
                • 2014-08-18
                • 1970-01-01
                • 2011-02-18
                • 1970-01-01
                • 1970-01-01
                • 2017-09-30
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多