如何将Office文件转化为PDF文件

来源:互联网 发布:中国汽车产销量数据 编辑:程序博客网 时间:2024/04/30 15:38
系统要求:安装了VS,Office及Acrobat(含Distiller).注意是Acrobat,不是Reader。

具体到我的机器,是VS.Net 2003, Office 2003 和 Acrobat7.0(含Distiller 7.0)

这里所谓的Office文件指的是Word的.doc,Excel的xls等等。

首先想到的自然是在程序中构造一个Excel程序对象(也可能是Word,PPT等,视情况而定),然后执行那个Convert to Adobe PDF命令,但是这个命令执行时会跳出一个对话框,要求用户输入PDF文件名。因为很多情况下我们需要在后台“悄悄的”转化,所以这个方法不太好。

第二个方法是构造一个Acrobat对象,然后直接调用Acrobat.Open( *.xls ),最后调用Acrobat.Save( *.pdf )。这个方法虽然不需要人为干预,即不需要用户去输入那个PDF文件名,但是过程中会跳出来一系列窗口:Excel窗口,Distiller窗口等等,于是整个过程显得很乱,我们需要寻找一个更好的方法。

在Google上大概搜了一下,还真找到了一个方法。大概的意思是先将xls通过distiller打印到一个PostScript文件,然后使用Distiller api将其进一步转为PDF文件。下面的代码首先将source.xls转化为medium.ps,然后将medium.ps转为destination.pdf。

Excel.ApplicationClass ap = new Excel.ApplicationClass();
Excel.Workbook wb = null;

wb = ap.Workbooks.Open(@"C:/source.xls",Type.Missing,Type.Missing
,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);

wb.PrintOut( Type.Missing ,Type.Missing ,1,
false,"Acrobat Distiller", true, true, @"C:/medium.PS"); //这步在我的Acrobat 7.0下会出现问题,但是有很多人这样做,我想可能以前的版本不会有问题

wb.Close(false,Type.Missing,Type.Missing);

ap.Quit();

ACRODISTXLib.PdfDistillerClass ds = new PdfDistillerClass();

ds.bShowWindow = 0;
ds.bSpoolJobs = 0;

ds.FileToPDF(@"C:/medium.ps",
@"C:/destination.pdf",
@"Standard");

理论上这段代码完全可以满足我们的要求了:既没有要求用户输入的对话框,也没有烦人的一堆窗口。不过执行的时候还是出了问题,跳出了这么一个窗口:

“When you create a PostScript file you have to send the host fonts.Please go to the printer properties,"Adobe PDF Settings"
page and turn OFF the option "Do not send fonts to Distiller"”

大意是说要把Adobe PDF的printer properties上,把"Do not send fonts to Distiller"前面的选项去掉才行.但是这是需要用户手动设置的,能不能编程实现呢?

有问题,找Google.这次搜索的结果是,这是一个"FAQNA"问题:Frequently Asked Question, Never Answered. 有很多人碰到了同样的问题,但是似乎没有人给出解答.看来只能自力更生了.

考虑到这个printer properties可以在控制面板->打印机和传真->Adobe PDF上进行设置,结合以往经验:大部分控制面板的选项与注册表里的某项有对应关系。于是自然想到,如果反复设置那个"Do not..."选项,同时监视注册表改动,也许可以看出一些蛛丝马迹来。

果然,发现了两处可疑点:

1) 注册项:HKCU/PRINTERS/DEVMODEPERUSER
 名字 Adobe PDF
 类型 REG_BINARY
   值的变化:当"Do not..."选项选中时,在偏移量03AC出值为01, 当选项未选中时,03AC处为00

2) 注册项:HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print/Printers/Adobe PDF/PrinterDriverData
   名字 DistillerHostFontHasMostFonts
   类型 REG_DWORD
   值的变化:当"Do not..."选项选中时,值为1, 当选项未选中时,值为0

进一步的实验表明,第一点完全可以控制那个选项的状态,每次我把它设为01,选项就被选中,设为00则是未选中。

剩下的问题就简单了,每次转化之前通过改注册表把那个选项去掉,转化完成后再把注册表改回来,我们的目的也就达到了。

PS:我可能是第一个解决这个问题的人,小小的得意一下,呵呵