问题:

使用Adobe Reader将一份pdf文件通过我的虚拟打印机输出后(输出的是中间文件,等同于EMF文件),查看的时候发现有时候是乱码。最简单的必现步骤:

1、使用Adobe Reader打开pdf文件,选择我的虚拟打印机打印(取消掉adobe打印高级选项中“作为图像打印”),生成中间文件。

2、此时可以通过工具查看这个中间文件(EMF),发现并没有乱码。

3、关闭刚才打印的Adobe Reader打开的Pdf文件,再次查看中间文件,这时候就乱码了。

分析:

根据上面的必现步骤,再测试使用FoxitReader、JisuPdf打开pdf文件然后选择我的虚拟打印机打印,都没有复现。此外,生成中间文件后,即使重新用Adobe Reader打开pdf,查看中间文件的时候,仍然是乱码。

根据上述现象,去对比使用JisuPdf和Adobe Reader执行打印后生成的中间文件的区别,发现存在比较大的区别。猜测Adobe Reader在打印输出的时候为不存在的字体创建了临时字体文件,所以Adobe Reader在没关闭的时候查看不会乱码,一旦关闭了就删掉了临时文件,所以就乱码了。

比如我第一次输出的是中文文件A,不关闭Adobe Reader,查看A正常。关闭Adobe Reader查看A乱码,再次打开Adobe Reader并打印出B,查看A乱码,B不乱码。由此说明,创建的这个临时字体文件,还是和对应的中间文件相关联的,并不是所有的都一样。

我分别比较上述A和B文件内容上的区别,发现其中一个区别就是EMR_EXTCREATEFONTINDIRECTW结构中的字段不一样,而且有个比较明显的字段内容lfFaceName不一样。

查看MSDN上对EMR_EXTCREATEFONTINDIRECTW的介绍,基本可以确定就是Adobe Reader在打印输出这个pdf文件的时候创建了临时字体文件,所以一旦Adobe Reader进程关闭了,就会删除临时字体文件导致中间文件乱码。这也说明了为什么直接输出到打印机时不会,而通过我的虚拟打印机输出中间文件,如果在同一台机器上不关闭Adobe Reader进程时将中间文件输出到真实打印机不会乱码,而在另一台机器上输出会乱码。

为了确认这个问题,我使用JisuPdf和FoxitReader再分别打印出中间文件C和D。用A和C、A和D比较,发现C和D中都不存在EXTCREATEFONTINDIRECTW这个记录,由此证明以上结论。

也就是说,我这个pdf文件中使用了非内嵌并且系统尚未安装的字体,pdf阅读器在打开的时候使用了相关的字体去替换显示。

进一步分析:

现在问题转变成,为什么Adobe Reader在打印时会调用CreateFontIndirect(生成EXTCREATEFONTINDIRECTW记录),而JisuPdf和FoxitReader却不会?

另外如果生成的EMF中有EXTCREATEFONTINDIRECTW记录,如何根据这个记录创建好需要的字体从而不乱码显示呢?

经过自己解析EMF中的记录进行绘制,发现是可以通过调用CreateFontIndirect函数去实现这条EXTCREATEFONTINDIRECTW记录的,但是仍然是乱码,也就是说无法找到实际能与之匹配上的字体。

解决方案:

问题拖了比较久,最终也没找到好的解决方案,目前采用的办法是对于这种情况,要么直接使用勾选上adobe reader的矢量图打印(这种方式比较万能,原理是将每页文档都转变成一张图片,相应的占据的空间也大,并且慢很多),要么就干脆换一个pdf阅读器,比如国产的foxit。

 

pdf打印乱码问题的更多相关文章

  1. 开源免费且稳定实用的.NET PDF打印组件itextSharp(.NET组件介绍之八)

    在这个.NET组件的介绍系列中,受到了很多园友的支持,一些园友(如:数据之巅. [秦时明月]等等这些大神 )也给我提出了对应的建议,我正在努力去改正,有不足之处还望大家多多包涵.在传播一些简单的知识的 ...

  2. AndroidStudio开发Java工程(解决java控制台中文打印乱码+导入jar包运行工程)

    这篇分享一点个人AS开发java工程经验,虽然有时候还是得打开eclipse来运行java项目,但能用AS的时候还是尽量用AS,毕竟一个字,爽~ 废话不多说,进入正题. 一.开发Java工程 你有两种 ...

  3. 解决idea控制台打印乱码问题

    idea控制台打印乱码,用起来总别扭,也是在网上搜索了一番,靠一点猜测解决了. 首先打开你自己的idea的安装目录下(即右键桌面图标,点击打开文件所在位置),然后找到idea.exe.vmoption ...

  4. 基于iTextSharp的PDF操作(PDF打印,PDF下载)

    基于iTextSharp的PDF操作(PDF打印,PDF下载) 准备 1. iTextSharp的简介 iTextSharp是一个移植于java平台的iText项目,被封装成c#的组件来用于C#生成P ...

  5. NetSuite实现pdf打印中的条形码的功能

    2020-11-27 提起NS,在程序员这一块应该不怎么被人知道,算是比较小众的一门技术了,毕竟Netsuite兴起的时间算不上早,进入中国的时间更晚,除了从事这一块的程序员,可能都没有见过,恰好我是 ...

  6. .Net下的PDF打印

    简单研究了一下.Net下的PDF打印,一路发现了很多小坑. 第三方组件 这里使用的解析PDF的组件是mupdf,特点和C#调用在 这里 有介绍. 实现的功能 支持页面大小.边距.打印机选择.打印机dp ...

  7. 驰骋CCFlow开源工作流程引擎如何设置PDF打印

    前言 经常有驰骋CCFlow爱好者朋友提问关于打印相关问题.在这篇博文中大家介绍一下工作流引擎CCFlow的HTML打印和PDF打印,针对Java版本和.NET版本有不同的操作步骤,包括开关设置.水印 ...

  8. Java 创建PDF打印小册子

    概述 PDF打印小册子是指将PDF格式文档在打印成刊物前需要提前进行的页面排版,以便在打印后装订成册.下面以Java代码展示如何来实现.这里调用Free Spire.PDF for Java中的Pdf ...

  9. libreoffice转换文件为pdf文件乱码问题解决办法

    最近系统需要一个office文件预览功能 解决方案为使用libreoffice将office文件转换为pdf文件,然后使用swftools将pdf文件转换为swf文件 最后在前台使用flexpaper ...

随机推荐

  1. c++回调编程本质

    1. boost:bind获得一个函数对象,就像函数指针一样,这个行为可以作为回调 2. bosot:bind的函数对象可以保存别的对象的引用,回调对象的成员函数 3. boost:function是 ...

  2. 尚未解决的intellij问题:补充措施

    2016-12-06 遇到问题 D:\software\apache-tomcat-7.0.57\bin\catalina.bat run [2016-12-06 09:54:52,342] Arti ...

  3. 对话框 自定义 IOS风格 包青天

    activity     private void showDialog1() {         message = "您输入的邮箱后缀不是公司邮箱地址\n将导致您的借款审核不通过,请重新 ...

  4. (转)如何将ecshop首页主广告位的flash轮播替换为js轮播

    转之--http://www.ecshoptemplate.com/article-1710.html 这个ecshop很常见,因为现在比起flash难以修改,js更加符合人们的使用习惯,而默认ecs ...

  5. 判断iPhone和iPad 判断设备版本

    //判断iPhone和iPad #define IS_IPHONE (!IS_IPAD) #define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInt ...

  6. oracle查询表信息(索引,外键,列等)

    oracle中查询表的信息,包括表名,字段名,字段类型,主键,外键唯一性约束信息,索引信息查询SQL如下,希望对大家有所帮助:1.查询出所有的用户表 select * from user_tables ...

  7. php 与 ajax 获取123的案例

    同事问我,咱们从数据库里面获取数据,用ajax的方式展示到前台页面.啥都不说了,动手写个案例吧. 1,建立一个页面: <!DOCTYPE html PUBLIC "-//W3C//DT ...

  8. 【COGS1672】难存的情缘

    [题目描述] 一天机房的夜晚,无数人在MC里奋斗着... 大家都知道矿产对于MC来说是多么的重要,但由于矿越挖越少,勇士们不得不跑到更远的地方挖矿,但这样路途上就会花费相当大的时间,导致挖矿效率底下. ...

  9. Windows Phone获得IsolatedStorage中指定目录下的所有文件

    在Windows Phone 中对隔离存储空间中的文件操作需要通过System.Io.IsolatedStorage下的类进行操作 获得指定文件夹下的所有文件: 参数:是指定文件夹的路径加上通配符,格 ...

  10. 深入浅出理解QTimeLine类

    网上找了下QTimeLIne类的介绍,要么就是代码一贴自己看去,要么就是说不到重点,正巧自己项目遇到这个类,在这里写一下,给需要的同学看下. 因为我最近需要有动画方面配合时间间隔触发QGraphics ...