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

猜你喜欢

转载自blog.csdn.net/sazass/article/details/82187643