#include "pdf_print_helper.h"

pdf_print_helper::pdf_print_helper()
{

}

pdf_print_helper::~pdf_print_helper()
{
if (ctx != nullptr && init_status)
{
if (pix !=nullptr)
fz_drop_pixmap(ctx, pix);
if (doc != nullptr)
fz_drop_document(ctx, doc);
if (ctx != nullptr)
fz_drop_context(ctx);
}
}

bool pdf_print_helper::init(QString &message)
{
if (init_status)
return true;
else
{
init_status = init_mupdf_lib(message);
return init_status;
}
}

bool pdf_print_helper::init_mupdf_lib(QString &message)
{
//创建上下文
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
if (!ctx)
{
message = QString::fromLocal8Bit("不能创建PDF上下文!");
return false;
}
//注册文档控制
fz_try(ctx)
fz_register_document_handlers(ctx);
fz_catch(ctx)
{
message = QString::fromLocal8Bit("无法注册文档处理:") + QString::fromLocal8Bit(fz_caught_message(ctx));
fz_drop_context(ctx);
return false;
}
return true;
}

bool pdf_print_helper::print_pdf(printer_print_pdf_info &print_info, QString &message)
{
if (print_info.pdf_path.empty())
return false;

//打开文档
fz_try(ctx)
doc = fz_open_document(ctx, print_info.pdf_path.c_str());
fz_catch(ctx)
{
message = QString::fromLocal8Bit("打开文件pdf文件失败:")+ QString::fromLocal8Bit(fz_caught_message(ctx));
fz_drop_context(ctx);
return false;
}

//取得总的页数
fz_try(ctx)
page_count = fz_count_pages(ctx, doc);
fz_catch(ctx)
{
message = QString::fromLocal8Bit("不能计算pdf页数!") + QString::fromLocal8Bit(fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}

if (page_number < 0 || page_number >= page_count)
{
message = QString::fromLocal8Bit("当前页码: ") + QString::number(page_number + 1) + QString::fromLocal8Bit("超范围总数:") + QString::number(page_count);
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
// (QPrinter::PrinterResolution);
if (print_info.printer_name.empty())
{
printer.setPrinterName(QPrinterInfo::defaultPrinterName());
}
else
printer.setPrinterName(QString::fromLocal8Bit(print_info.printer_name.c_str()));

printer.setFullPage(true);
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setCopyCount(print_info.print_copies);
printer.setResolution(print_info.printer_dpi);

QPainter painter;
painter.begin(&printer);

//根据打印DPI默认300 计算缩放以及旋转
zoom = print_info.printer_dpi / 72.0f;
fz_scale(&ctm, zoom, zoom);
fz_pre_rotate(&ctm, rotate);

for (int i = 0; i < page_count; i++)
{
fz_try(ctx)
pix = fz_new_pixmap_from_page_number(ctx, doc, i, &ctm, fz_device_rgb(ctx), 0);
fz_catch(ctx)
{
message = QString::fromLocal8Bit("绘制pdf出错") + QString::fromLocal8Bit(fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
unsigned char *samples = pix->samples;
int width = fz_pixmap_width(ctx, pix);
int height = fz_pixmap_height(ctx, pix);
QImage image(samples, width, height, pix->stride, QImage::Format_RGB888);
painter.drawImage(QRect(0, 0, width, height), image);
printer.setFullPage(true);
if (i < page_count - 1)
printer.newPage();
}
return painter.end();
}

打印pdf的更多相关文章

  1. C# 打印PDF文件之使用不同打印机打印所有页面或部分页面

    C# 打印PDF文件之使用不同打印机打印所有页面或部分页面 最近在逛国外各大编程社区论坛的时候,发现很多人都在问一个关于PDF文件打印的问题:打印时如何选择非默认打印机并设置打印页面的范围.而一般情况 ...

  2. Winform 打印PDF顺序混乱,获取打印队列

    工作中PDF打印顺序混乱着实让我疼痛了好久,其实决绝方法非常简单,但没有想到这个点子的时候确实让我走了很多弯路 这里文章写出来并不是为了炫耀什么,只是觉得发现些好东西就分享出来而已,同时也做个记录,方 ...

  3. 关于这两天研究Java打印pdf方法的记录

    这两天在研究Java调用打印机打印PDF文件的方法,学到了不少东西,特别来记录一下. 关于Java打印网上最多的而且也是Java正统的打印方法就是使用PrintService,一套比較标准的打印代码例 ...

  4. PDFBox创建并打印PDF文件, 以及缩放问题的处理.

    PDFBox带了一些很方便的API, 可以直接创建 读取 编辑 打印PDF文件. 创建PDF文件 public static byte[] createHelloPDF() { ByteArrayOu ...

  5. C#调用Python脚本打印pdf文件

     介绍:通过pdf地址先将文件下载到本地,然后调用打印机打印,最后将下载的文件删除. 环境:windows系统.(windows64位) windows系统中安装python3.6.2环境 资料: O ...

  6. C# 打印PDF文档的10种方法

    操作PDF文档时,打印是常见的需求之一.针对不同的打印需求,可分多种情况来进行,如设置静默打印.指定打印页码范围和打印纸张大小.双面打印.黑白打印等等.经过测试,下面将对常见的几种PDF打印需求做一些 ...

  7. C#使用iTextSharp+ZXing.Net+FreeSpire.PDF生成和打印pdf文档

    项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.Net+FreeSpire.PDF三个类库实现了生成pdf.生成条形码和打印pdf功能. 首先在项 ...

  8. 安卓打印实现打印pdf文档

    先声明一下,此处的打印非pos打印机打印和蓝牙打印机打印,如果想查找打印小票的pos打印机请进入下面的传送门,蓝牙打印目前没做过,有做过的请指教. pos打印机传送门: 1. https://www. ...

  9. CRM UI 打印PDF

    这是项目上看到的绝技^_^ 1.画SF.这步就不说了 2.确定参数,写SF打印PDF函数 FUNCTION zsrv_print_to_pdf . *"------------------- ...

  10. Chrome 打印PDF技巧

    Chrome 打印PDF技巧 原文地址:https://github.com/zhongxia245/blog/issues/22 欢迎star 本教程,使用Mac电脑进行演示. 常规的Chrome打 ...

随机推荐

  1. HDU 5253 连接的管道(Kruskal算法求解MST)

    题目: 老 Jack 有一片农田,以往几年都是靠天吃饭的.但是今年老天格外的不开眼,大旱.所以老 Jack 决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行灌溉了.当老 J ...

  2. Java Bad version

    Eclipse的三个地方需要重新设置: 在工程上点右键,选属性,三个地方: Java Build Path Java Compiler Project Facets:这个地方还可以设置tomcat的r ...

  3. Uploadify火狐出现302错误

    $(function () { var auth = "@(Request.Cookies[FormsAuthentication.FormsCookieName] == null ? st ...

  4. api.closeFrame

    关闭frame closeFrame({params}) params name: 类型:字符串 默认值:无 描述:(可选项)frame 名字,不传时关闭当前 frame 示例代码 api.close ...

  5. Oracle表闪回功能

    1.启用表闪回首先要在表上支持行移动(在数据字典中设置标识来标识该操作可能会改变行ID,即同一条数据闪回成功后主键都一样,但行ID其实已经发生变化了) SQL> alter table base ...

  6. 构造用于1个方法在多线程环境下重复多次执行测试的通用方法 C#

    static void MultithreadsCycleTestWithSameMethod(int threadNumber, int cycleNumber, ThreadStart actio ...

  7. AutoFac在项目中应用的体会

    AutoFac的工作原理就是:注册类并映射到接口,通过注入后返回相应实例化的类! 先来简单介绍下Autofac的使用      1.通过Nuget或代码安装autofac 安装autofac :ins ...

  8. HDU3085(KB2-G 双向bfs)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. WinForm中使用CrystalReport水晶报表——基础,分组统计,自定义数据源

    开篇 本篇文章主要是帮助刚开始接触CrystalReport报表的新手提供一个循序渐进的教程.该教程主要分为三个部分1)CrystalReport的基本使用方法:2)使用CrystalReport对数 ...

  10. 在GDI+中如何实现以左下角为原点的笛卡尔坐标系

    今天写了一个求点集合的凸包的一个算法,虽然结果求解出来了,但是想将过程用GDI+绘制出来,就需要将点绘制出来,然而c#GDI+中绘图的坐标与我们常用数学中笛卡尔坐标系是不一样的,所以就要转换GDI+中 ...