C#中調用PDFCreator生成PDF文件

前一陣子做了一個生成報表的小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生成的調用是單線程的。還有打印機的名字用的是默認值,沒有修改,不過這些問題是難不倒各位看官的。


原文地址:http://blog.csdn.NET/mcai4gl2/article/details/7294625

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章