zoukankan      html  css  js  c++  java
  • ASP.NET,flexpaper,SWFTools 实现简单的PDF显示(二)Itexsharp生成pdf字体问题

    1、最近工作因为需要实现PDF的生成,保存,显示,打印等问题,使用了Itexsharp+FlexPaper

     FlexPaper在这篇中已经有了少许的介绍了: http://www.cnblogs.com/zhanghaomars/archive/2013/02/20/2918792.html

    不过在后来的使用中也发现了很多的问题,接下来一一道来。

    (1)先生成pdf,然后转换为swf

    说明:string args = "  -t " + PdfFileFullPath + " -s flashversion=9  -o " + SwfSaveFullPath;这个方法对以前的方法做了修改,因为有些pdf文件无法转换或者转换了无法显示,加了 flashversion=9 ,使得所有的都转换为9.0版本的swf

            /// <summary>
            /// 将数据写入文件
             /// </summary>
           /// <param name=" _bt">pdf二进制</param> 
        /// <param name="filename">文件名称</param> 
    /// <param name="folderpath">文件名称</param> private void WriteDatatoFile(byte[] _bt, string filename) { FileStream fs; //返回包含指定网站的虚拟目录的物理路径 string filepath = System.Web.HttpContext.Current.Server.MapPath(@"..\Content\WSTemp\pdf"); string Allfilename = filename + ".pdf"; string path = filepath + "\\" + Allfilename; //判断文件是否存在 if (System.IO.File.Exists(path)) { fs = new FileStream(path, FileMode.Truncate); } else { fs = new FileStream(path, FileMode.CreateNew); } BinaryWriter br = new BinaryWriter(fs); br.Write(_bt, 0, _bt.Length); br.Close(); fs.Close(); }
             /// <summary>
            /// 建立pdf并把pdf转为swf
            /// </summary>
            /// <param name="pdfFilename">pdf的文件名</param>
            public void CreatePdfAND2Swf(string pdfFilename)
            {
                string cmdStr = "C:\\Program Files (x86)\\SWFTools\\pdf2swf.exe";(pdf2swf安装的路径)
                string PdfFilePath = System.Web.HttpContext.Current.Server.MapPath(@"..\Content\WSTemp\pdf");
                string PdfFileFullPath = PdfFilePath + "\\" + pdfFilename + ".pdf";
                string SwfSavePath = System.Web.HttpContext.Current.Server.MapPath(@"..\Content\WSTemp\pdf");
                string SwfSaveFullPath = SwfSavePath + "\\" + pdfFilename + ".swf";
                string args = "  -t " + PdfFileFullPath + " -s flashversion=9  -o " + SwfSaveFullPath;
                ExecutCmd(cmdStr, args);
            }
    
            /// <summary>
            /// 调用线程pdf转为swf
            /// </summary>
            /// <param name="cmd"></param>
            /// <param name="args"></param>
            public static void ExecutCmd(string cmd, string args)
            {
                using (Process p = new Process())
                {
                    p.StartInfo.FileName = cmd;
                    p.StartInfo.Arguments = args;
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardOutput = false;
                    p.StartInfo.CreateNoWindow = true;
                    p.Start();
                    //p.PriorityClass = ProcessPriorityClass.Normal;
                    p.WaitForExit();
                }
            } 

    (不过实践中也发现有些字体生产的PDF也无法用pdf2swf.exe转换,或者转换成SWF后无法显示,这将在接下来的博文中一一道来)

    因为项目需要根据不同的需求通过代码动态地生成pdf的二进制文件,因此用到了Itexsharp,可字体这部分就遇到了很多问题。

    (1)BaseFont.createFont方法第二、三个参数的意思无需知道,第一个参数显示就是字体文件存放的位置(即字体的样式)

       //直接通过本机路径调用系统字体:
           BaseFont font = BaseFont.CreateFont("C:\\windows\\fonts\\ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

    注:以上方法发布时需要在服务器上也存在该路径或字体文件
           //把字体文件放到项目文件中(注:ARIALUNI.TTF文件来自系统文件C:\\windows\\fonts\\ARIALUNI.TTF):
           string fontpath = Server.MapPath(@"~/Font");
           BaseFont fontinsert = BaseFont.CreateFont(fontpath+"ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

    注:这种方式就是把字体放在项目中,无需当心服务器上是否有该字体或者路劲

    (2)用(1)中的方法确实可以生成支持中文的PDF,但生成的PDF文件自己过大,具体的原因无法知道也没有深入了解(但个人认为是ARIALUNI.TTF字体的原因,该字体22M左右),但因为项目需要生成字节小的PDF文件只能想办法解决了。

    方法如下:

           //直接通过本机路径调用系统字体:
           BaseFont font = BaseFont.CreateFont("C:\\windows\\fonts\\simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
           //把字体文件放到项目文件中(注:ARIALUNI.TTF文件来自系统文件C:\\windows\\fonts\\simsun.ttc,1):
           string fontpath = Server.MapPath(@"~/Font");
           BaseFont fontinsert = BaseFont.CreateFont(fontpath+"simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

    用(2)中这种字体生成的文书字节就比较小,具体原因也不太清楚,不过达到了效果,同时这种字体也可以用 FlexPaper中提到的pdf2swf.exe把生成的PDF转换为SWF并用 FlexPaper进行显示。

    (3)BaseFont.AddToResourceSearch("../Bin/iTextAsian.dll");
            BaseFont.AddToResourceSearch("~/Bin/iTextAsianCmaps.dll");
            BaseFont font = BaseFont.CreateFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

            使用(3)这种字体生成的pdf字节很小,但我在程序中这样用会报错,不知道什么原因,望大侠告知!不过这种方式生成的pdf文件,用FlexPaper中提到的pdf2swf.exe把生成的PDF转换为SWF会失败!!!

    注:iTextAsian.jar是一个亚洲字体包,里面包含几种简单的亚洲字体,其中包含简体中文字体。使用iTextAsian.jar,其实是采用了iText字体解决方案中的“Fonts from jar”方式,从jar包中提取字符集编码方式和字体。这样,就能够正常的显示中文信息。

    这种方法虽然能够正常地显示中文信息,但是有一个缺点,就是只有一种字体。因为iText官方网站提供的iTextAsian.jar包中只包 含几种简单的亚洲字体,对于简体中文来说,只有宋体。因此,采用这种方法生成的PDF中,中文字体只能为宋体,无法显示其他字体。当然,可以通过扩展 iTextAsian.jar的方式解决这个问题,在这个包中增加其他的字体。但是我还没找到其他的扩展包,也许以后会有人实现其他字体。

    附:

    //楷体字
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //方正舒体
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZSTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //方正姚体
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZYTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //仿宋体
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //黑体
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文彩云
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STCAIYUN.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文仿宋
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STFANGSO.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文细黑
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXIHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文新魏
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINWEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文行楷
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINGKA.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //华文中宋
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STZHONGS.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //隶书
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMLI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //宋体&新宋体
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //宋体-方正超大字符集
                //BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SURSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                //幼圆
                BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

    未完待续。。。。。。。。

  • 相关阅读:
    lc739
    POJ3280
    6.2
    5.30
    5.28
    5.26
    5.26
    5.25
    从0搭建vue项目
    docker安装jenkins并使用
  • 原文地址:https://www.cnblogs.com/zhanghaomars/p/3025151.html
Copyright © 2011-2022 走看看