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

xiaoxiao2021-02-27  207

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

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

2、添加几个变量:

BOOL m_bPrintAsPdf; // 是否输出pdf,初始化为FALSE CString 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; } else return 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; } else PrintOut(pDC, pInfo); 试了下,效果还不错。PS: 当然可以使用各种pdf虚拟打印机,不过放在安装包里也不方便,所以我选择了这种方式。
转载请注明原文地址: https://www.6miu.com/read-14286.html

最新回复(0)