欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VS中导出PDF

程序员文章站 2022-07-13 13:31:12
...

需要准备的头文件:
VS中导出PDF

///- 2. 初始化PDF
HPDF_Doc CPageOutput::initPdf(char * filename)
{
    HPDF_Doc pdf;   
    pdf = HPDF_New(error_handler,NULL); ///-创建一个pdf句柄
    if (NULL == pdf)    {   return NULL;        }   ///- 创建句柄错误

    int retEnv = setjmp(g_env);
    if (0!=retEnv)                                  ///-查看是否句柄产生异常
    {
        CString warningMsg = CString("创建/替换 PDF文件异常, 以\"")+CString(filename) + 
            CString("\"命名的文件可能已经打开,请检查并关闭文件后 重试!");
        MessageBox(warningMsg, TEXT("提示"));
        ///     HPDF_Free(pdf);
        return NULL;
    }
    //// 设定压缩模式
    HPDF_STATUS retStat = HPDF_SetCompressionMode(pdf,HPDF_COMP_ALL);

    if (HPDF_OK == retStat)
    {
        retStat = HPDF_SetPageMode(pdf,HPDF_PAGE_MODE_USE_OUTLINE);
        if (HPDF_OK != retStat)  {  return NULL;  }
    }
    else
    {   return NULL;    }

    //// 设置CN Simple 中文简体 字符
    retStat = HPDF_UseCNSFonts(pdf);
    if (HPDF_OK != retStat)  {  return NULL;  }
    //// 设置CN Simple 中文简体 编解码
    retStat = HPDF_UseCNSEncodings(pdf);
    if (HPDF_OK != retStat)  {  return NULL;  }

    return pdf;
}
//-- a. 添加页面
bool CPageOutput::pdfAddPage()
{
    o_page = HPDF_AddPage(o_pdf);   ///- 在文档中新增一页
    o_font = HPDF_GetFont(o_pdf, "SimSun", "GB-EUC-H"); ///- 生成字体
    ///- 设置页面大小为A4,后面一个参数是描述
    HPDF_STATUS retStat = HPDF_Page_SetSize(o_page,HPDF_PAGE_SIZE_A4,HPDF_PAGE_PORTRAIT);   
    if (HPDF_OK != retStat)     {   return false;   }
    return true;
}
//-- b. PDF画线
bool CPageOutput::drawHLine (HPDF_Page page,Point2f startPt, Point2f endPt)
{
    HPDF_STATUS retStat = HPDF_Page_BeginText(page);
    if (HPDF_OK != retStat)     {   return false;       }
    retStat = HPDF_Page_MoveTextPos(page, startPt.x, startPt.y);
    if (HPDF_OK != retStat)     {   return false;       }
    retStat = HPDF_Page_EndText(page);
    if (HPDF_OK != retStat)     {   return false;       }
    retStat = HPDF_Page_MoveTo(page, startPt.x, startPt.y);
    if (HPDF_OK != retStat)     {   return false;       }
    retStat = HPDF_Page_LineTo(page, endPt.x, endPt.y);
    if (HPDF_OK != retStat)     {   return false;       }
    retStat = HPDF_Page_Stroke(page);
    if (HPDF_OK != retStat)     {   return false;       }

    return true;
}
//-- c. PDF文本输出
bool CPageOutput::pdfTextOut(HPDF_Page Page,HPDF_Font font, HPDF_REAL fontSz, Point2f pt,const char* szText)
{
    HPDF_STATUS retStat;

    retStat = HPDF_Page_BeginText(Page);                                ///- 设置页面 
    if (HPDF_OK != retStat)     { return false; }
    retStat = HPDF_Page_SetFontAndSize(Page, font, fontSz); ///- 设置字体和字号
    if (HPDF_OK != retStat)     { return false; }
    retStat =HPDF_Page_MoveTextPos(Page, pt.x,pt.y);                ///- 设置开始位置
    if (HPDF_OK != retStat)     { return false; }
    retStat = HPDF_Page_ShowText(Page, szText);                     ///- 设定要显示的字符串
    if (HPDF_OK != retStat)     { return false; }
    retStat = HPDF_Page_EndText(Page);                                  ///- 页面结尾
    if (HPDF_OK != retStat)     { return false; }

    return true;
}
///- 3. 打印页面框架   调用b,  c,   打印包括文件标题 表头 页脚等内容---------(3.7改)
bool CPageOutput::pdfPrintPgFrame(int nowID, int pgTotal)
{
    char spec[128] ="规格; ";
    char batch[128] ="批次: ";
    strcat_s(spec,128,CStringA(o_spec).GetBuffer());
    strcat_s(batch,128,CStringA(o_batch).GetBuffer());

    const char * page_title = "XXXXXXX检测结果",    ///文件页眉
        * page_1st_spec =spec,
        * page_1st_batch = batch,
        * page_1st_oper = "操作员:______________",             
        * page_1st_timeTag = "日期:______________",           
        * table_col_id = "序号",              ///- 字号(pond):10.5      表头信息-序号
        * table_col_result = "检测结果";        ///- 字号(pond):10.5      表头信息-结果值
    ////=PDF生成的 过程 Y坐标是从左下角开始的

    float tablePosY = 0.0;
    bool boolRet=false;


    if (2 > nowID)  ///- 如果是首页,则打印文件头
    {   ///- 显示首页页眉         
        boolRet = pdfTextOut(o_page, o_font, 12.0f, Point2f(8.0f*o_scaleX, o_pgHeight-3.0f*o_scaleY), page_title);      
        if (!boolRet)   {   return false;   }

        ////    操作员:______________ (5.5, 4.0)日期:______________  (12.5, 4.0)
        boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(5.5f*o_scaleX, o_pgHeight-4.0f*o_scaleY), page_1st_spec);
        if (!boolRet)   {   return false;   }
        boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(12.5f*o_scaleX, o_pgHeight-4.0f*o_scaleY), page_1st_batch);
        if (!boolRet)   {   return false;   }


        //// 显示首页 标记信息      操作员:______________ (5.5, 5.0)       日期:______________   (12.5, 5.0)
        boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(5.5f*o_scaleX, o_pgHeight-5.0f*o_scaleY), page_1st_oper);
        if (!boolRet)   {   return false;   }
        boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(12.5f*o_scaleX, o_pgHeight-5.0f*o_scaleY), page_1st_timeTag);
        if (!boolRet)   {   return false;   }
        //// 定义表头Y坐标    序号  (4.5, 4.8)  检测结果(10.5, 4.8); 横线坐标 (3, 5.0)(18, 5.0)
        tablePosY = o_pgHeight-5.8f*o_scaleY;

        ///-画纵向线分割每组------------------------(3.7改)
        //横坐标为每组间隔中点:       6;  10.5;   15  
        boolRet = drawHLine(o_page, Point2f(6.0f*o_scaleX,o_pgHeight-6.0f*o_scaleY), Point2f(6.0f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
        boolRet = drawHLine(o_page, Point2f(10.5f*o_scaleX,o_pgHeight-6.0f*o_scaleY), Point2f(10.5f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
        boolRet = drawHLine(o_page, Point2f(15.0f*o_scaleX,o_pgHeight-6.0f*o_scaleY), Point2f(15.0f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
    }   
    else
    {   ///- 定义表头Y坐标序号  (4.5, 1.8)  检测结果(10.5, 1.8); 横线坐标 (3, 2.0)(18, 2.0)
        tablePosY = o_pgHeight-1.8f*o_scaleY;

        ///-画纵向线分割每组------------------------(3.7改)
        //横坐标为每组间隔中点:   5.75;   10.25;  14.75;      
        boolRet = drawHLine(o_page, Point2f(6.0f*o_scaleX,o_pgHeight-2.0f*o_scaleY), Point2f(6.0f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
        boolRet = drawHLine(o_page, Point2f(10.5f*o_scaleX,o_pgHeight-2.0f*o_scaleY), Point2f(10.5f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
        boolRet = drawHLine(o_page, Point2f(15.0f*o_scaleX,o_pgHeight-2.0f*o_scaleY), Point2f(15.0f*o_scaleX, 1.3f*o_scaleY));
        if (!boolRet)   {   return false;   }
    }

    //// 显示表头--------(3.7改)
    /*
    每个PDF打印4列;把一列序号和一列结果分为一组,共四组;
    组内,列于列间隔2个单位;组与组之间间隔2.5个单位;每页总宽21个单位,总长30个单位;
    表头排列横坐标如下;
    2-3.5 | 6.5-8  |    11-12.5 |   15.5_17
    */
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(2.0f*o_scaleX, tablePosY), table_col_id);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(6.5f*o_scaleX, tablePosY), table_col_id);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(11.0f*o_scaleX, tablePosY), table_col_id);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(15.5f*o_scaleX, tablePosY), table_col_id);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(3.5f*o_scaleX, tablePosY), table_col_result);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(8.0f*o_scaleX, tablePosY), table_col_result);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(12.5f*o_scaleX, tablePosY), table_col_result);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(17.0f*o_scaleX, tablePosY), table_col_result);
    if (!boolRet)   {   return false;   }

    //// 页脚分割线          横线坐标  首页: start (3, 5.0)  end (18, 5.0)    其它:  start (3, 2.0) end (18, 2.0)
    boolRet = drawHLine(o_page, Point2f(1.5f*o_scaleX, tablePosY-0.2f*o_scaleY), Point2f(19.5f*o_scaleX, tablePosY-0.2f*o_scaleY));
    if (!boolRet)   {   return false;   }
    //// 显示页脚
    char indexBuf[20]="";
    sprintf_s(indexBuf, "%d/%d", nowID, pgTotal);
    //// 画水平线分割 并打印 ”第  12/25   页“
    boolRet = drawHLine(o_page, Point2f(1.5f*o_scaleX,1.3f*o_scaleY), Point2f(19.5f*o_scaleX, 1.3f*o_scaleY));
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(9.0f*o_scaleX, 0.8f*o_scaleY), "第");
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(9.8f*o_scaleX, 0.8f*o_scaleY), indexBuf);
    if (!boolRet)   {   return false;   }
    boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(11.0f*o_scaleX, 0.8f*o_scaleY), "页");
    if (!boolRet)   {   return false;   }

    ///-画纵向线分割每组------------------------(3.7改)
    boolRet = drawHLine(o_page, Point2f(3.0f*o_scaleX,1.3f*o_scaleY), Point2f(18.0f*o_scaleX, 1.3f*o_scaleY));


    return true;
}
//-- d. 内容整页打印   调用c 循环打印内容,一次打印一整页;
bool CPageOutput::pdfPrintTxt(int lineTotal, int pgID, vector<CString> resBank)
{
    char lineBuf[10]="", resultBuf[20]="";
    bool boolRet=false;
    float beginPos=0.0;
    int gapID=0,            ///- 序号偏差,即当不在首页的时候,将偏差值加到序号上面
        realLineID=0;   ///- realLineID  当前序号和gapID组合后的序号真实值
    //首页每组最多存储45条数据;首页最多存储45*4 = 180 条数据;
    //其他页最多存储53*4 = 212条数据;
    if ( 2 > pgID)
    {   ///- 首页的 首行  Y坐标
        beginPos = o_pgHeight-6.0f*o_scaleY;
        for (int lineID=1; lineID<=lineTotal; lineID++)
        {   ///- 开始写结果数据
            realLineID = lineID+gapID;
            ZeroMemory(lineBuf,10);
            ZeroMemory(resultBuf, 20);
            sprintf_s(lineBuf, "%d", realLineID);
            sprintf_s(resultBuf, "%S", resBank[realLineID-1]);
            switch((lineID - 1) / 45)
            {
            case 0:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(2.0f*o_scaleX,  beginPos-0.5f*lineID*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(3.5f*o_scaleX,    beginPos-0.5f*lineID*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 1:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(6.5f*o_scaleX,  beginPos-0.5f*(lineID - 45)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(8.0f*o_scaleX,    beginPos-0.5f*(lineID - 45)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 2:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(11.0f*o_scaleX, beginPos-0.5f*(lineID - 90)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(12.5f*o_scaleX,   beginPos-0.5f*(lineID - 90)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 3:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(15.5f*o_scaleX, beginPos-0.5f*(lineID - 135)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(17.0f*o_scaleX,   beginPos-0.5f*(lineID - 135)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            }

        }
    }
    else
    {   ///- 其他页面的首行  Y坐标
        beginPos = o_pgHeight-2.0f*o_scaleY;
        gapID = 45*4 + (pgID-2)*53*4;
        for (int lineID=1; lineID<lineTotal; lineID++)
        {   ///- 开始写结果数据
            realLineID = lineID+gapID;
            ZeroMemory(lineBuf,10);
            ZeroMemory(resultBuf, 20);
            sprintf_s(lineBuf, "%d", realLineID);
            sprintf_s(resultBuf, "%S", resBank[realLineID-1]);
            switch((lineID - 1) / 53)
            {
            case 0:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(2.0f*o_scaleX,  beginPos-0.5f*lineID*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(3.5f*o_scaleX,    beginPos-0.5f*lineID*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 1:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(6.5f*o_scaleX,  beginPos-0.5f*(lineID - 53)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(8.0f*o_scaleX,    beginPos-0.5f*(lineID - 53)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 2:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(11.0f*o_scaleX, beginPos-0.5f*(lineID - 106)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(12.5f*o_scaleX,   beginPos-0.5f*(lineID - 106)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            case 3:
                boolRet = pdfTextOut(o_page, o_font, 10.5f, Point2f(15.5f*o_scaleX, beginPos-0.5f*(lineID - 159)*o_scaleY), lineBuf);
                if (!boolRet)   {   return false;   }
                boolRet=pdfTextOut(o_page, o_font, 10.5f, Point2f(17.0f*o_scaleX,   beginPos-0.5f*(lineID - 159)*o_scaleY), resultBuf);
                if (!boolRet)   {   return false;   }
                break;
            }
        }
    }

    return true;
}
///- 4. 打印到PDF文档中  调用a 添加页面, 调用3打印页面框架, 调用d打印全部的检测结果-------------(3.7改);
bool CPageOutput::print2PDF(int recordCnt, vector<CString> resBank)
{
    o_scaleX = o_pgWidth/PAGE_WIDTH, o_scaleY = o_pgHeight/PAGE_HEIGHT;
//// 首页 最多47条记录,第一行坐标   1   (4.5, 5.5)  129.8973 (11.5, 5.5) 
///  其他 最多53条记录,第一行坐标   48  (4.5, 2.5)  192.9378 (11.5, 2.5)   48 = 首页47+第二页的1
    int nowID=0, pgTotal=0, lastCnt=0;

    if (recordCnt<181)      {   pgTotal=1;  }
    else
    {
        recordCnt -= 45*4;
        pgTotal =1 + recordCnt/212;
        lastCnt = recordCnt%212;
        ///- 如果不是完整页面 则添加一个页面
        if (0 < lastCnt)    {   pgTotal = pgTotal +1;       }
    }   
    bool boolRet=false;
    //// 打印首页框架
    boolRet = pdfPrintPgFrame(1, pgTotal);
    if (!boolRet)   {   return false;   }

    char lineBuf[10]="";
    if (pgTotal<2)  ///- 结果条目少于1页的情况
    {
        boolRet = pdfPrintTxt(recordCnt, 1, resBank);
        if (!boolRet)   {   return false;   }
    } 
    else                ///- 条目多于1页的情况
    {
        int pgID=1;
        boolRet = pdfPrintTxt(180, pgID, resBank);      ///- 打印首页
        if (!boolRet)   {   return false;   }
        //// 打印中间页
        for (pgID=2; pgID<(pgTotal); pgID++)
        {
            if (pdfAddPage())
            {
                boolRet = pdfPrintPgFrame(pgID, pgTotal);
                if (!boolRet)   {   return false;   }
                boolRet = pdfPrintTxt(212, pgID, resBank);
                if (!boolRet)   {   return false;   }
            }
            else    {   return false;   }   
        }

        //// 打印尾页
        if (pdfAddPage())
        {
            boolRet = pdfPrintPgFrame(pgID, pgTotal);
            if (!boolRet)   {   return false;   }
            boolRet = pdfPrintTxt(lastCnt, pgTotal, resBank);
            if (!boolRet)   {   return false;   }
        } 
        else    {   return false;   }
    }

    return true;
}
相关标签: PDF