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);

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

posted @ 2013-04-17 14:40  蓦然浩怪  阅读(1517)  评论(0编辑  收藏  举报