开源wkhtmltopdf使用心得 (三)
前面已经在程序里面使用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名称中文部分是乱码。