[点晴永久免费OA]C#中调用PDFCreator生成PDF文件
当前位置:点晴教程→点晴OA办公管理信息系统
→『 经验分享&问题答疑 』
前一阵子做了一个生成报表的小project,生成的报表是关于股价的记录。没有什么现成的包和第三方程序给我们用,听说WPF渲染的页面可以之间存成PDF,不过只是道听途说,没敢真正实践,最后还是用了自己以前搞过的方法,Office Interop,在一个word文档中插入很多placeholder搞成template,然后用C#代码动态把PlaceHolder变成数据,然后保存。这个方法其实挺强大,不过有几个限制和不爽的地方。第一,程序运行的机器上要有Office安装,word是必须的,如果要生成图的话,还需要Excel. 第二,.NET Office Interop本质上还是COM的封装,性能和稳定性就不能太苛求了。第三,Office Interop搞起来还是挺烦的。抱怨了半天,不过这个方法还是可行的。不过最后要求生成PDF形式的报表,但是Office没有PDF生成的支持,这怎么办?想起自己每每需要生成PDF文件的时候直接用PDFCreator虚拟打印机就可以了,查了一下,果然,PDFCreator有COM API. 这下问题解决了。 在C#中如何调用PDFCreator生成PDF文件呢? 第一步:安装PDFCreator (这个好像是废话) 第二步:创建C#项目,加入PDFCreator.exe COM引用 第三步:参见如下代码: public override void Process(ITask task, int index) { if (!File.Exists(Path.Combine(FromLocation, FromFilename))) { throw new FileNotFoundException("File: " + Path.Combine(FromLocation, FromFilename) + " does not exists"); } Monitor.Enter(lockObject); clsPDFCreator creator = null; try { creator = new clsPDFCreator(); creator.eError += new __clsPDFCreator_eErrorEventHandler(creator_eError); creator.eReady += new __clsPDFCreator_eReadyEventHandler(creator_eReady); String paramters = "/NoProcessingAtStartup"; if (!creator.cStart()) { throw new Exception("Cannot launch PDFCreator. Error: " + Error); } var opt = creator.cOptions; opt.UseAutosave = 1; opt.UseAutosaveDirectory = 1; opt.AutosaveDirectory = this.ToLocation; opt.AutosaveFormat = 0; opt.AutosaveFilename = this.ToFilename; creator.cOptions = opt; creator.cClearCache(); creator.cDefaultPrinter = "PDFCreator"; if (!creator.cIsPrintable(Path.Combine(FromLocation, FromFilename))) { throw new Exception("File: " + Path.Combine(FromLocation, FromFilename) + " is not printable."); } creator.cPrintFile(Path.Combine(FromLocation, FromFilename)); creator.cPrinterStop = false; Ready = false; var duration = new TimeSpan(0, 0, 0, TimeoutInSec); DateTime lastCheck = DateTime.Now; DateTime startTime = lastCheck; while (!Ready && ((lastCheck - startTime) < duration)) { System.Threading.Thread.Sleep(500); lastCheck = DateTime.Now; } creator.cPrinterStop = true; Thread.Sleep(1000); creator.cClose(); if (!Ready) { throw new Exception("PDF creation failed. This maybe due to timeout."); } } finally { Monitor.Exit(lockObject); } } void creator_eReady() { this.Ready = true; } void creator_eError() { Error = creator.cError.Description; } 代码很好懂,自己很懒,没有把代码重新写成一个Project,直接把Project中的代码贴上了,大家要用的话,还要稍微修改一下。要说的一点是PDFCreator不支持多线程,所以如果程序本身是多线程的话,需要在代码中增加一个锁机制,保证PDF生成的调用是单线程的。还有打印机的名字用的是默认值,没有修改,不过这些问题是难不倒各位看官的。 该文章在 2020/4/3 22:12:39 编辑过 |
关键字查询
相关文章
正在查询... |