網絡採集軟件核心技術剖析系列(4)---使用C#語言如何將html網頁轉換成pdf(html2pdf)

一 本系列隨筆概覽及產生的背景html

本系列開篇受到你們的熱烈歡迎,這對博主是莫大的鼓勵,此爲本系列第四篇,但願你們繼續支持,爲我繼續寫做提供動力。git

本身開發的豆約翰博客備份專家軟件工具問世3年多以來,深受廣大博客寫做和閱讀愛好者的喜好。同時也不乏一些技術愛好者諮詢我,這個軟件裏面各類實用的功能是如何實現的。github

該軟件使用.NET技術開發,爲回饋社區,現將該軟件中用到的核心技術,開闢一個專欄,寫一個系列文章,以饗廣大技術愛好者。數據庫

本系列文章除了講解網絡採編發用到的各類重要技術以外,也提供了很多問題的解決思路和界面開發的編程經驗,很是適合.NET開發的初級,中級讀者,但願你們多多支持。編程

不少初學者常有此類困惑,「爲何我書也看了,C#相關的各個方面的知識都有所瞭解,但就是無法寫出一個像樣的應用呢?」windows

這其實仍是沒有學會綜合運用所學知識,鍛煉出編程思惟,創建起學習興趣,我想該系列文章也許會幫到您,希望如此。瀏覽器

開發環境:VS2008網絡

本節源碼位置:https://github.com/songboriceboy/csharphtml2pdf框架

源碼下載辦法:安裝SVN客戶端(本文最後提供下載地址),而後checkout如下的地址:https://github.com/songboriceboy/csharphtml2pdf函數

系列文章提綱以下:

二 第四節主要內容簡介(使用C#語言如何將html網頁轉換成pdf)

本節示例代碼的運行界面以下圖所示。點擊生成PDF按鈕後,程序作了3件事情:

(1)下載網頁地址中博文的正文;

(2)下載博文中的所有圖片到本地;

(3)將文字和圖片用後面所說的工具生成爲PDF文檔。

 

點擊生成PDF按鈕後,該程序後自動下載網址中對應的網頁,並在可執行程序所在目錄生成一個以博文標題命名的文件夾,以下圖所示:

該文件夾中包含了網頁正文的html文檔(index.html文件),正文中的所有圖片,以及最後生成的pdf文檔。以下圖所示:

 

生成的pdf文檔效果以下圖所示:

 

將html文件轉換成pdf文件所須要的技術很是高,咱們須要寫一個既能解析html文檔(相似瀏覽器功能),又能生成pdf文檔(須要掌握pdf文檔結構細節)的工具,幸運的是一個有一個好用免費的現成的工具,那就是wkhtmltopdf(http://www.wkhtmltopdf.org/)。

首先,咱們來看一下如何經過這個工具來轉html文檔到pdf文檔。下載對應平臺的可執行文件(windows平臺的能夠在我上面的github地址中下載到,在PDFLIB文件夾中)。文件夾中有4個文件,以下圖所示:

 

進入DOS界面,執行命令wkhtmltopdf.exe www.cnblogs.com cnblogs.pdf,第一個參數是要轉化的網頁地址(www.cnblogs.com),

第二個參數是要保存的pdf文件名稱(cnblogs.pdf),這個命令執行成功以後會發如今當前路徑下生成了一個cnblogs.pdf文件(我這裏的路徑是d:/PDFLIB/)。

生成的PDF文件以下:

接下來咱們須要作的是將這個生成過程整合到咱們本身開發的軟件中。

由上面的作法能夠很容易得出,咱們須要使用C#語言來實現進程間通訊,即在咱們本身的代碼中啓動wkhtmltopdf.exe進程,並傳遞給wkhtmltopdf.exe其所須要的參數。

C#中啓動一個進程能夠利用Process類,下面咱們就來看一下具體作法,核心代碼以下:

   public bool _html2pdf(string fileName)
        {
            string strPdfSavedPath = m_strPath;
            if (!Directory.Exists(strPdfSavedPath))//判斷是否存在
            {
                Directory.CreateDirectory(strPdfSavedPath);//建立新路徑
            }

            if (!File.Exists(strPdfSavedPath + fileName + ".pdf"))
            {

                string strHtmlSavedPath = m_strPath;
                string file_flvbind = Application.StartupPath + @"\PDFLIB\wkhtmltopdf.exe";
                //MoveFolderTo(fileName, Application.StartupPath + @"\PDFLIB\");
                //生成ProcessStartInfo
                ProcessStartInfo pinfo = new ProcessStartInfo(file_flvbind);
                //pinfo.WorkingDirectory = Application.StartupPath + @"\PDFLIB\";
                pinfo.WorkingDirectory = strHtmlSavedPath;
                //設置參數
                StringBuilder sb = new StringBuilder();
                sb.Append("--footer-line ");
                sb.Append("--footer-center \"powered by 際爲軟件事務所(http://www.cnblogs.com/ice-river)\" ");
                sb.Append("\"" + "index.html\"");
              
                sb.Append(" \"" + strPdfSavedPath + fileName + ".pdf" + "\"");

                pinfo.Arguments = sb.ToString();
                //隱藏窗口
                pinfo.WindowStyle = ProcessWindowStyle.Hidden;
                //啓動程序
                
                Process p = Process.Start(pinfo);
                p.WaitForExit(); //DeleteFiles(Application.StartupPath + @"\PDFLIB\");
                if (p.ExitCode == 0)
                {
                    DelegatePara dp = new DelegatePara();
                    dp.strLog = "生成 [" + fileName + ".pdf] 成功!\n";
                    
                    m_delesPDF.Refresh(dp);
                    return true;
                }
                else
                {
                    DelegatePara dp = new DelegatePara();
                    dp.strLog = "生成 [" + fileName + ".pdf] 失敗!\n";
                    m_delesPDF.Refresh(dp);
                    return false;
                }
            }
            else
            {
                DelegatePara dp = new DelegatePara();
                dp.strLog = "生成 [" + fileName + ".pdf] 成功!\n";
                m_delesPDF.Refresh(dp);
                return true;
            }
        }

 上面代碼段中,紅色文字的部分是核心所在,這裏簡單解釋一下:

ProcessStartInfo pinfo = new ProcessStartInfo(file_flvbind);

上面代碼中構造函數中的參數很重要,指定了正確的要運行進程所在的文件路徑;
pinfo.WorkingDirectory = strHtmlSavedPath;
上面這句代碼指定的咱們要生成pdf文件的原材料(也即html文件和所有圖片所在文件路徑);

pinfo.Arguments保存的是進程wkhtmltopdf.exe須要的執行參數,拿剛纔所舉出的例子來講就是
wkhtmltopdf.exe www.cnblogs.com cnblogs.pdf
「--footer-center \"powered by 際爲軟件事務所(http://www.cnblogs.com/ice-river)\" 是傳遞給wkhtmltopdf.exe進程的一個附加參數,用來在生成的pdf文檔中添加頁腳,以下圖所示:

pinfo.Arguments = sb.ToString();這句就是提供給進程的參數;

Process p = Process.Start(pinfo);這句是啓動wkhtmltopdf.exe進程;
p.WaitForExit();這句是等待wkhtmltopdf.exe進程結束,
if (p.ExitCode == 0)
若是進程的結束碼是0,進程執行成功,不然說明進程執行失敗。
代碼就解釋到這裏,具體更詳細的代碼你們能夠自行下載學習。
須要指出的是,這段運行另一個進程的代碼具備通用性,您徹底能夠用它來在本身的程序中運行其餘的進程,實現進程間通訊。

三 下節預告

使用C#語言如何將html網頁轉換成txt(html2txt)。

做者: 宋波
出處: http://www.cnblogs.com/ice-river/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,往後必有一番做爲!旁邊有「推薦」二字,你就順手把它點了吧,相得準,我分文不收;相不許,你也好回來找我!
相關文章
相關標籤/搜索