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);
未完待续。。。。。。。。