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


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

本系列開篇受到大家的熱烈歡迎,這對博主是莫大的鼓勵,此為本系列第四篇,希望大家繼續支持,為我繼續寫作提供動力。

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

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

本系列文章除了講解網絡采編發用到的各種重要技術之外,也提供了不少問題的解決思路和界面開發的編程經驗,非常適合.NET開發的初級,中級讀者,希望大家多多支持。

很多初學者常有此類困惑,“為什么我書也看了,C#相關的各個方面的知識都有所了解,但就是沒法寫出一個像樣的應用呢?”

這其實還是沒有學會綜合運用所學知識,鍛煉出編程思維,建立起學習興趣,我想該系列文章也許會幫到您,但願如此。

開發環境: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/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得准,我分文不收;相不准,你也好回來找我!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM