前面已經在程序里面使用wkhtmltopdf.exe進行網頁轉換。但是存在一些弊端,而且也不方便我們使用,接下來我們將使用wkhtmltox庫提供的API接口將wkhtmltox添加到我們自己的項目中:
vs2008中添加使用wkhtmltopdf開源項目
1.下載wkhtmltox-0.12.3.2_msvc2013-win32.exe安裝
網站:http://wkhtmltopdf.org/
2.將wkhtmltopdf的安裝目錄下的lib和include添加到vs中
a.打開vs選擇工具-選項-項目和解決方案-VC++目錄
包含文件中添加inlcude路徑
庫文件中添加lib路徑
3.在項目中添加
#include <wkhtmltox/pdf.h>
#pragma comment(lib, "wkhtmltox.lib")
4. 將wkhtmltox.dll復制到當前項目生成的exe目錄下
vs2010中添加lib和include
項目右擊-屬性-VC++目錄
/**************************************************** 頭文件中添加以下代碼 ****************************************************/ #include <wkhtmltox\pdf.h> #include <wkhtmltox\image.h> static void pdf_progress_changed(wkhtmltopdf_converter* c, int p); // 類成員函數作為回調函數 static void pdf_phase_changed(wkhtmltopdf_converter* c); static void pdf_error(wkhtmltopdf_converter* c, const char* msg); static void pdf_warning(wkhtmltopdf_converter* c, const char* msg); static void pdf_finish(wkhtmltopdf_converter* c, int p);
static CmyHtmlToPdfDlg* myDlg; // 作為類指針在回調函數中使用類非靜態變量和非靜態成員函數
/**************************************************** 源文件中添加以下代碼 ****************************************************/ CmyHtmlToPdfDlg::CmyHtmlToPdfDlg(CWnd* pParent /*=NULL*/) : CDialog(CmyHtmlToPdfDlg::IDD, pParent) , m_editPipe_data(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); myDlg = this; } CmyHtmlToPdfDlg * CmyHtmlToPdfDlg::myDlg = NULL; void CmyHtmlToPdfDlg::pdf_progress_changed(wkhtmltopdf_converter* c, int p){ printf("%3d%%\r", p); fflush(stdout); CString str; str.Format("pdf progress changed %s",wkhtmltopdf_progress_string(c)); myDlg->m_editPipe.ReplaceSel(str + "\r\n"); } void CmyHtmlToPdfDlg::pdf_phase_changed(wkhtmltopdf_converter* c){ int phase = wkhtmltopdf_current_phase(c); printf("pdf phase changed %s\n", wkhtmltopdf_phase_description(c,phase)); CString str; str.Format("%s", wkhtmltopdf_phase_description(c,phase)); myDlg->m_editPipe.ReplaceSel(str + "\r\n"); } void CmyHtmlToPdfDlg::pdf_error(wkhtmltopdf_converter* c, const char* msg){ fprintf(stderr, "Error: %s\n", msg); CString str; str.Format("pdf error %s", msg); myDlg->m_editPipe.ReplaceSel(str + "\r\n"); //AfxMessageBox(msg); } void CmyHtmlToPdfDlg::pdf_warning(wkhtmltopdf_converter* c, const char* msg){ fprintf(stderr, "Warning: %s\n", msg); CString str; str.Format("pdf warning %s", msg); myDlg->m_editPipe.ReplaceSel(str + "\r\n"); //AfxMessageBox(msg); } void CmyHtmlToPdfDlg::pdf_finish(wkhtmltopdf_converter* c, int p) { printf("%3d%%\r", p); //fflush(stdout); int iCode = wkhtmltopdf_http_error_code(c); int phase = wkhtmltopdf_current_phase(c); CString str2; str2.Format("%s", wkhtmltopdf_phase_description(c,phase)); myDlg->m_editPipe.ReplaceSel(str2 + "\r\n"); CString str,str1, tmp; str.Format("error code %d", iCode); str1.Format("finish code %d", p); tmp = str + "\r\n" + str1; myDlg->m_editPipe.ReplaceSel(tmp + "\r\n"); if (iCode == 0 && p != 0 && str2 == "Done") { //MessageBox("下載完成"); if (myDlg == NULL) { return; } myDlg->mess(); } else { ; } } void CmyHtmlToPdfDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知處理程序代碼 CString strAddress, tmpName; m_editAddress.GetWindowText(strAddress); BOOL isOpen = FALSE; //是否打開(否則為保存) CString defaultDir = "D:\\"; //默認打開的文件路徑 CString fileName = "newFile.pdf"; //默認保存的文件名 CString filter = "文件(*.pdf)|*.pdf||"; //文件過慮的類型 CFileDialog openFileDlg(isOpen, defaultDir, fileName, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, filter, NULL); openFileDlg.GetOFN().lpstrInitialDir = "D:\\my\\"; //默認打開目錄 INT_PTR result = openFileDlg.DoModal(); CString filePath = defaultDir + "\\" + fileName; if(result == IDOK) { filePath = openFileDlg.GetPathName(); } //CWnd::SetDlgItemTextW(IDC_EDIT_DEST, filePath); // std::string str = CW2A(tmpName); // const char *tmName = str.c_str(); // // // std::string strAddr = CW2A(strAddress); // const char *tmAddr = strAddr.c_str(); // CString sWebAddress; // sWebAddress = "D:\\htmltopdf\\wkhtmltopdf.exe"; // sWebAddress += " www.hao123.com"; // sWebAddress += " D:\\my資料庫\\我的資料.pdf"; //ShellExecute(this->m_hWnd, "open", "D:\\htmltopdf\\wkhtmltopdf.exe", sWebAddress, NULL, SW_SHOW); CString sWebAddress, strLocaPath; sWebAddress = strAddress; strLocaPath = filePath; // strLocaPath = drive; // strLocaPath += "\\" + fileName; // strTmpPath = strLocaPath; std::string tmpPath = strLocaPath; std::string tmpAddr = sWebAddress; wkhtmltopdf_global_settings* gs; wkhtmltopdf_object_settings* os; wkhtmltopdf_converter* c; int i = 0; wkhtmltopdf_init(i); gs = wkhtmltopdf_create_global_settings(); wkhtmltopdf_set_global_setting(gs, "out", tmpPath.c_str()); os = wkhtmltopdf_create_object_settings(); wkhtmltopdf_set_object_setting(os, "page", tmpAddr.c_str()); c = wkhtmltopdf_create_converter(gs); wkhtmltopdf_set_progress_changed_callback(c, CmyHtmlToPdfDlg::pdf_progress_changed); wkhtmltopdf_set_phase_changed_callback(c, CmyHtmlToPdfDlg::pdf_phase_changed); wkhtmltopdf_set_error_callback(c, CmyHtmlToPdfDlg::pdf_error); wkhtmltopdf_set_warning_callback(c, CmyHtmlToPdfDlg::pdf_warning); wkhtmltopdf_set_finished_callback(c, CmyHtmlToPdfDlg::pdf_finish); wkhtmltopdf_add_object(c, os, NULL); if( !wkhtmltopdf_convert(c) ) fprintf(stderr, "Convertion failed!"); // int iCode = wkhtmltopdf_http_error_code(c);// icode =0 是成功 // printf("httpErrorCode: %d\n", wkhtmltopdf_http_error_code(c)); // if (!iCode) // { // AfxMessageBox("SUCESS"); // } // wkhtmltopdf_destroy_global_settings(gs); // // wkhtmltopdf_destroy_object_settings(os); // // wkhtmltopdf_destroy_converter(c); // // iCode = wkhtmltopdf_deinit(); }
注意:保存的目錄不能有中文路徑和中文名稱,如果路徑中有中文,則不能轉換,如果名稱中有中文,則轉換的pdf名稱中文部分是亂碼。
