您的位置:首页 > 编程语言 > C#

C#中调用PDFCreator生成PDF文件

2012-09-03 09:32 441 查看
http://blog.csdn.net/mcai4gl2/article/details/7294625

前一阵子做了一个生成报表的小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引用

第三步:参见如下代码:

[csharp]
view plaincopy

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生成的调用是单线程的。还有打印机的名字用的是默认值,没有修改,不过这些问题是难不倒各位看官的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: