pdf打印乱码问题
问题:
使用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打印乱码问题的更多相关文章
- 开源免费且稳定实用的.NET PDF打印组件itextSharp(.NET组件介绍之八)
在这个.NET组件的介绍系列中,受到了很多园友的支持,一些园友(如:数据之巅. [秦时明月]等等这些大神 )也给我提出了对应的建议,我正在努力去改正,有不足之处还望大家多多包涵.在传播一些简单的知识的 ...
- AndroidStudio开发Java工程(解决java控制台中文打印乱码+导入jar包运行工程)
这篇分享一点个人AS开发java工程经验,虽然有时候还是得打开eclipse来运行java项目,但能用AS的时候还是尽量用AS,毕竟一个字,爽~ 废话不多说,进入正题. 一.开发Java工程 你有两种 ...
- 解决idea控制台打印乱码问题
idea控制台打印乱码,用起来总别扭,也是在网上搜索了一番,靠一点猜测解决了. 首先打开你自己的idea的安装目录下(即右键桌面图标,点击打开文件所在位置),然后找到idea.exe.vmoption ...
- 基于iTextSharp的PDF操作(PDF打印,PDF下载)
基于iTextSharp的PDF操作(PDF打印,PDF下载) 准备 1. iTextSharp的简介 iTextSharp是一个移植于java平台的iText项目,被封装成c#的组件来用于C#生成P ...
- NetSuite实现pdf打印中的条形码的功能
2020-11-27 提起NS,在程序员这一块应该不怎么被人知道,算是比较小众的一门技术了,毕竟Netsuite兴起的时间算不上早,进入中国的时间更晚,除了从事这一块的程序员,可能都没有见过,恰好我是 ...
- .Net下的PDF打印
简单研究了一下.Net下的PDF打印,一路发现了很多小坑. 第三方组件 这里使用的解析PDF的组件是mupdf,特点和C#调用在 这里 有介绍. 实现的功能 支持页面大小.边距.打印机选择.打印机dp ...
- 驰骋CCFlow开源工作流程引擎如何设置PDF打印
前言 经常有驰骋CCFlow爱好者朋友提问关于打印相关问题.在这篇博文中大家介绍一下工作流引擎CCFlow的HTML打印和PDF打印,针对Java版本和.NET版本有不同的操作步骤,包括开关设置.水印 ...
- Java 创建PDF打印小册子
概述 PDF打印小册子是指将PDF格式文档在打印成刊物前需要提前进行的页面排版,以便在打印后装订成册.下面以Java代码展示如何来实现.这里调用Free Spire.PDF for Java中的Pdf ...
- libreoffice转换文件为pdf文件乱码问题解决办法
最近系统需要一个office文件预览功能 解决方案为使用libreoffice将office文件转换为pdf文件,然后使用swftools将pdf文件转换为swf文件 最后在前台使用flexpaper ...
随机推荐
- Bellman_ford POJ 3259 Wormholes
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 41728 Accepted: 15325 Descr ...
- checkbox 删除
先创建del.php文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- POJ 3162 Walking Race(树的直径+单调队列)
题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的 ...
- 线程技术 ☞ Future模式
线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...
- CentOS6.6x86_64 部署 Nginx1.62+MySQL5.6.20+PHP5.6.4
准备工作 切换到管理员身份 su - 安装编译扩展 yum install -y gcc-c++ 创建数据库目录.代码目录 mkdir /mnt/data /mnt/www 安装Nginx 1.6.2 ...
- 关于android应用闪屏的几种情况
1.主菜单进入某应用闪屏: 常见是一个空的activity作为launcher属性,实际上它什么事业没干,真正干事情的是从它通过intent启动的activity. 例子: public class ...
- Linux和windows下清除svn保存的账号密码信息
linux是什么用户登录就是什么用户的home下,如root用户就是/root,如果xiangdong就是/home/xiangdong 用Svn时会有一种需求是需要换个帐号测试一下什么的,但往往有缓 ...
- iOS学习笔记(十四)——打电话、发短信
电话.短信是手机的基础功能,iOS中提供了接口,让我们调用.这篇文章简单的介绍一下iOS的打电话.发短信在程序中怎么调用. 1.打电话 [[UIApplication sharedApplicatio ...
- Swift - 25 - 控制转移和二维数组
//: Playground - noun: a place where people can play import UIKit // fallthrough // fallthrough会在当前c ...
- javascript获取对象宽度和高度
标签元素的宽高值获取//绝对宽度Obj.offsetWidth//绝对高度Obj.offsetHeight 以下是获取窗口对象的宽高值.clientHeight 获取对象的高度,不计算任何边距.边 ...

