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

4 篇文章 0 订阅

最近尝试使用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虚拟打印机,不过放在安装包里也不方便,所以我选择了这种方式。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值