HMTL转PDF 图片(JPG BMP)

HTML转为pdf,或者转为图片,有个开源工具wkhtmltoX,参照官网主页:https://wkhtmltopdf.org/    一个好东西。


实际应用:

下载安装,手动命令行 wkhtmltopdf.exe  http://www.baidu.com/  c:\.pdf

软件也可以通过调用exe去转换,总感觉多少有点2。


重点来了,好在官方提供dll。看到dll是不是很happy,官方还提供了.h 和.lib是不是更happy。这些就在安装目录下,直接拷贝使用即可。而且目录分配分配很规范bin  lib include。


废话少说。只需要一点点耐心,你就可以调用wkhtmltopdf生成pdf,并获取各个回调过程:

/****************************************************
头文件中添加以下代码
****************************************************/
#include
#include

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();  
    }

    CString sWebAddress, strLocaPath;
    sWebAddress = strAddress;
    strLocaPath = filePath;

    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!");
}



也许看到topdf,想当然认为把pdf改成image就可以转成图片了,然而并不是这样:

wkhtmltoimage_global_settings* gs;
    wkhtmltoimage_converter* c;
    int i = 0;
    wkhtmltoimage_init(i);

    gs = wkhtmltoimage_create_global_settings();

    wkhtmltoimage_set_global_setting(gs, "out", string_To_UTF8(tmpPath).c_str());
    wkhtmltoimage_set_global_setting(gs,"in", string_To_UTF8(tmpAddr).c_str());
    
    c = wkhtmltoimage_create_converter(gs,"");
    wkhtmltoimage_set_error_callback(c, CHTMLPrinter::wktox_error);
    
    if( !wkhtmltoimage_convert(c) )
    {
        fprintf(stderr, "Convertion failed!");
        return FALSE;
    }

当然大同小异,只是没有这个wkhtmltoimage_object_settings对象而已,我们不可想当然认为有。

具体原因,其他参数怎么用参数是什么,请参照 官网的Library Documentation 网址:https://wkhtmltopdf.org/libwkhtmltox/

你可能感兴趣的:(c++)