输出pdf文件的一个简单方法

来源:互联网 发布:数据分析行业的职位 编辑:程序博客网 时间:2024/05/07 16:46

最近尝试使用pdflib输出pdf文档,但是pdflib的方法很多,要将打印输出与pdf匹配,需要编写很多代码,而且一旦需要修改,也是个麻烦事,所以就想了个偷懒的办法,如下:

1、在项目中加入pdflib支持,具体方法就不赘述了,网上有很多。

2、添加几个变量:

BOOL m_bPrintAsPdf;// 是否输出pdf,初始化为FALSECString m_strPdfFileName;HANDLE m_hPdfDevMode;HANDLE m_hPdfDevNames;
3、在输出pdf文档的响应函数中:
if(m_hPdfDevMode == NULL || m_hPdfDevNames == NULL){ // 使用windows自带的虚拟打印机作为输出媒介,如果没有可以手动安装,但是名称要一致GetPrinterDevice(_T("Microsoft XPS Document Writer"), &m_hPdfDevNames, &m_hPdfDevMode);}TCHAR BASED_CODE szFilter[] = _T("PDF Files(*.pdf)|*.pdf||");CFileDialog OpenFileDlg(FALSE, _T("pdf"), _T(""), OFN_HIDEREADONLY, szFilter, this);if(OpenFileDlg.DoModal() == IDCANCEL) return;m_strPdfFileName = OpenFileDlg.GetPathName();m_bPrintAsPdf = TRUE;CMyView::OnFilePrint();return;
4、在OnPreparePrinting函数中改成:
if(m_bPrintAsPdf){PRINTDLG pd;AfxGetApp()->GetPrinterDeviceDefaults(&pd);AfxGetApp()->SelectPrinter(m_hPdfDevNames, m_hPdfDevMode, FALSE);pInfo->m_bDirect = TRUE;pInfo->m_pPD->m_pd.Flags |= PD_PRINTSETUP | PD_RETURNDC;// Perform default MFC handling.BOOL b = DoPreparePrinting(pInfo);// Reinstall MFC's printer.AfxGetApp()->SelectPrinter(pd.hDevNames, pd.hDevMode, FALSE);pInfo->m_bDirect = FALSE;return b;}elsereturn DoPreparePrinting(pInfo);
5、在OnPrint函数中:
if(m_bPrintAsPdf){CRect rectClient = pInfo->m_rectDraw;CDC memDC;memDC.CreateCompatibleDC(pDC);CBitmap bmp;bmp.CreateCompatibleBitmap(pDC, rectClient.Width(), rectClient.Height());CBitmap* pOldBmp = memDC.SelectObject(&bmp);memDC.FillSolidRect(rectClient, RGB(255,255,255));// PrintOut就是打印输出函数PrintOut(&memDC, pInfo);// 下面将每一页保存成图片CImage TempImageObj;TempImageObj.Attach((HBITMAP)bmp.Detach());CString strPngFile;// AppDirectory是我的应用程序所在路径,获取方法这里不再描述strPngFile.Format("%s\\temp%d.png", AppDirectory, pInfo->m_nCurPage);if(E_FAIL == TempImageObj.Save(strPngFile)){DWORD dwError = GetLastError();LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL, GetLastError(), NULL, (LPTSTR) &lpMsgBuf, 0, NULL );MessageBox((LPCTSTR)lpMsgBuf, "ERROR", MB_OK | MB_ICONINFORMATION);LocalFree( lpMsgBuf );}memDC.SelectObject(pOldBmp);ReleaseDC(&memDC);// 所有图片全部生成,要保存到pdf文件了if(pInfo->m_nCurPage == pInfo->GetMaxPage()){m_bPrintAsPdf = FALSE;char szPdfFileName[500], szPngFileName[500];sprintf_s(szPdfFileName, 500, _T("%s"), m_strPdfFile);PDFlib pdf;float fTemp,fMaxData=0,fMinlength;pdf.set_parameter("license", "w700602-009100-731090-Y6WPH2-5SE4A2");if(pdf.open_file(szPdfFileName) == -1)MessageBox("打开文件出错!");pdf.set_info("Creator", "admin");pdf.set_info("Author", "my home");pdf.set_info("Title", "Convert to PDF");pdf.set_info("Subject", "PDF Creator");int i;for(i = 0; i < pInfo->GetMaxPage(); i++){strPngFile.Format("%s\\temp%d.png", AppDirectory, i + 1);sprintf_s(szPngFileName, 500, _T("%s"), strPngFile);int iImage = pdf.load_image("png", szPngFileName, "");if(iImage == -1){MessageBox("Save pdf file failed!");break;}pdf.begin_page_ext(rectClient.Width(), rectClient.Height(), "");pdf.place_image(iImage, 0, 0, 1);pdf.end_page_ext("");// 将临时图片文件删除DeleteFile(szPngFileName);}pdf.close();}return;}elsePrintOut(pDC, pInfo);
试了下,效果还不错。PS: 当然可以使用各种pdf虚拟打印机,不过放在安装包里也不方便,所以我选择了这种方式。
原创粉丝点击