一、转换解决方案

Office文件(doc、docx、xls、xlsx、ppt、pptx、txt七种格式)转换为PDF有很多办法,本文只从已实践的四种作解析说明。

1、调用Office自带组件服务转换

前提要求

  • 服务器上必须装Office,最低2007(注:2007安装完成后,需要单独下载PDF转换插件,附件里有),最好是2010以上。
  • 还需要在服务器上开启php的dcom扩展,参考网址如下:
    https://www.cnblogs.com/zhuchenglin/p/7586170.html
    注:32位的office配置office组件服务时,输入comexp.msc -32这个命令而不是dcomcnfg。

调用方法

此种方法本质上是PHP与C++语言的交互。Office从2010版以后,增加了转换PDF文件的COM插件(就是office的C++ SDK库),可以另存为PDF文件。如下图所示:

我们需要做的获取这个组件的API,然后调用即可。至于用什么语言,看自己需求吧。PHP的此处已经说过,文末会提供额外的python方式代码。

API地址及参考如下所示

https://docs.microsoft.com/zh-cn/office/vba/api/word.document.exportasfixedformat

缺陷

这种方式在实践中发现,带特殊对象的word文件,譬如公章等的非图片对象,用这个转换之后出现黑框的情况,所以只适用于普通的文档转换。而且转换文档偏慢。

2、采用开源Office软件libreOffice软件进行转换。

前提要求

服务器上需要安装libreOffice软件。下载地址:
https://zh-cn.libreoffice.org/download/download
在Path下配置环境变量

调用方法

参考:https://www.cnblogs.com/qlqwjy/p/9846904.html

缺陷

毕竟是开源软件,执行标准跟Microsoft Office不一样,所以转换之后颜色渲染粗细上会有差别,文字页数会有一定的偏移但并不影响(跟文档里的图片布局排版有关)。另外,对非图片对象的图片会自动转换为图片对象来保存,这点不错。

3、调用PDF虚拟打印机的方式转换

前提要求

客户端上安装PDF虚拟打印机,注意是客户端安装

目前虚拟打印机的厂商有很多家,除了Microsoft自带的,最权威的有Adobe acrobat即Adobe PDFMaker。
安装完成后,在office里会自动加载插件,保存选项里会多出一项:

还有一家是PDFCreator。官网可下载。下载地址:
https://www.pdfforge.org/pdfcreator

调用方法

  • 客户端上安转打印机后,由客户端触发调用,然后再动态的传到服务器端。
  • 目前调用的API暂时未找着,查到的都只是对PDF编辑、合并一类。如果有哪位大大找到了,还请劳烦告知我一声。此处先标记一下,以后再补充。

缺陷

几乎没有什么缺陷,最好的一种方式。唯一遗憾的是笔者未找到在服务器端安装后提供的API可供调用的。

二、 注意事项

  • 转换完成后,如果字体乱码或不一致,则应该是服务器缺少字体所致,安装后即可解决。
  • 带签章的文件转完后,签章盖住下方文字。原因是盖章之前未选择衬于文字下方。此处需告知客户在盖章前,必须选择“衬于文字下方”。
  • PHP的exec函数执行错误。原因是需要在php.ini里开启exec扩展即可。

三、扩展

根据研究,Office转换为html展示,或html转换为word、pdf展示,皆可参考以上方案。

四、Python代码示例

参考了这位大大的文章,做了多线程的优化且增加了日志记录,如下:

import os
import pythoncom
import threading
import loggingfrom win32com.client import constants, gencache, DispatchEx_Log = logging.getLogger("PDFConverter")class PDFConverter:def __init__(self, _pathname, _export_path=None, _is_async=True):""":param _pathname: 输入的文件夹或文件路径:param _export_path: 导出目录路径:param _is_async: 是否异步执行"""self._pathname = _pathnameself._export_path = _export_pathself._is_async = _is_asyncself._handle_postfix = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt']self._filename_list = list()def _parse_filenames(self):"""解析路径,获取当前路径下的所有文件"""full_pathname = os.path.abspath(self._pathname)if os.path.isfile(full_pathname):if self._is_legal_postfix(self._pathname):self._filename_list.append(full_pathname)else:raise TypeError('文件 {} 后缀名不合法!仅支持如下文件类型:{}。'.format(self._pathname, '、'.join(self._handle_postfix)))elif os.path.isdir(full_pathname):# 遍历的目录的地址, 返回的是一个三元组(root,dirs,files)# real_path为当前正在遍历的这个文件夹的地址# files为real_path文件夹中所有的文件for real_path, _, files in os.walk(full_pathname):for name in files:filename = os.path.join(full_pathname, real_path, name)if self._is_legal_postfix(filename):self._filename_list.append(os.path.join(filename))else:raise TypeError('文件/文件夹 {} 不存在或不合法!'.format(self._pathname))def _is_legal_postfix(self, filename):return filename.split('.')[-1].lower() in self._handle_postfix and not os.path.basename(filename).startswith('~')@staticmethoddef doc(input_file, export_file):"""doc 和 docx 文件转换"""pythoncom.CoInitialize()# gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)# 使用启动独立的进程wordApp = DispatchEx("PDFMakerAPI.PDFMakerApp")try:# wordApp.Visible = 0# wordApp.DisplayAlerts = 0# doc = wordApp.Documents.Open(input_file)# doc.ExportAsFixedFormat(export_file, constants.wdExportFormatPDF,#                         OptimizeFor=constants.wdExportOptimizeForPrint,#                         Item=constants.wdExportDocumentWithMarkup,#                         IncludeDocProps=True,#                         CreateBookmarks=constants.wdExportCreateHeadingBookmarks)# # 关闭# doc.Close()wordApp.CreatePDF(input_file, export_file)except Exception as e:_Log.error(input_file, "文件转换失败:", e)finally:if wordApp:wordApp.Quit()# 释放资源pythoncom.CoUninitialize()def docx(self, input_file, export_file):self.doc(input_file, export_file)def txt(self, input_file, export_file):self.doc(input_file, export_file)@staticmethoddef xls(input_file, export_file):"""xls 和 xlsx 文件转换"""pythoncom.CoInitialize()# gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)xlsApp = DispatchEx("Excel.Application")try:xlsApp.Visible = 0xlsApp.DisplayAlerts = 0books = xlsApp.Workbooks.Open(input_file, False)books.ExportAsFixedFormat(0, export_file)books.Close(False)except Exception as e:_Log.error(input_file, "文件转换失败:", e)finally:if xlsApp:xlsApp.Quit()# 释放资源pythoncom.CoUninitialize()def xlsx(self, input_file, export_file):self.xls(input_file, export_file)@staticmethoddef ppt(input_file, export_file):"""ppt 和 pptx 文件转换"""pythoncom.CoInitialize()pptApp = DispatchEx("PowerPoint.Application")try:pptApp.Visible = 0pptApp.DisplayAlerts = 0ppt = pptApp.Presentations.Open(input_file, False, False, False)ppt.ExportAsFixedFormat(export_file, 2, PrintRange=None)ppt.Close()except Exception as e:_Log.error(input_file, "文件转换失败:", e)finally:if pptApp:pptApp.Quit()# 释放资源pythoncom.CoUninitialize()def pptx(self, input_file, export_file):self.ppt(input_file, export_file)def converter(self):"""进行批量处理,根据后缀名调用函数执行转换"""_flag = 1_export_file_path = ""if self._export_path and os.path.isdir(self._export_path):_export_file_path = self._export_pathelse:_flag = 0# 解析目标文件路径,存入list,并确认最终导出的文件夹路径_export_file_pathtry:self._parse_filenames()except TypeError as e:_Log.error("解析目标文件/路径报错", e)return 1_Log.info('需要转换的文件数:%d' % len(self._filename_list))# threads = []for filename in self._filename_list:postfix = filename.split('.')[-1].lower()funcCall = getattr(self, postfix)# self._input_file = filenameif _flag is 0:_export_file_path = os.path.dirname(filename)export_file = os.path.join(_export_file_path, str(os.path.splitext(filename)[0]) + '.pdf')if self._is_async:t = threading.Thread(target=funcCall, args=(filename, export_file))# threads.append(t)t.start()else:funcCall(filename, export_file)# 开始调用start方法,同时开始所有线程# for i in range(0, len(self._filename_list)):#     threads[i].start()_Log.info('转换完成!')return 0if __name__ == "__main__":# 支持文件夹批量导入,也支持单个文件的转换# 默认异步导出到每个文件的对应文件下,也可指定相应目录folder = 'tmp'pathname = os.path.join(os.path.abspath('.'), folder)# pathname = 'test.doc'PDF = PDFConverter(pathname)PDF.converter()

其中

 gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)

并未用到,也可以用gencache去启动进程,此处不做探究。

不足之处,还请各位多多指教

Office文件转PDF的解决方案相关推荐

  1. python office转pdf_python 如何将office文件转换为PDF

    在平时的工作中,难免需要一些 小Tip 来解决工作中遇到的问题,今天的文章给大家安利一个方便快捷的小技巧,将 Office(doc/docx/ppt/pptx/xls/xlsx)文件批量或者单一文件转 ...

  2. office文件转换为pdf文件

    office文件转换为pdf文件 首先安装openoffice,自行百度 导入jar包,自行百度 引入坐标: <!-- 转pdf配置 --><dependency><gr ...

  3. python office转pdf linux_python 如何将office文件转换为PDF

    在平时的工作中,难免需要一些 小Tip 来解决工作中遇到的问题,今天的文章给大家安利一个方便快捷的小技巧,将 Office(doc/docx/ppt/pptx/xls/xlsx)文件批量或者单一文件转 ...

  4. Qt显示pdf系列2——QAxWidget打开Office文件及pdf

    序 一QAxwidget操作office 二QAxwidget操作pdf 三总结  承接上章,该扯皮的扯完了,直接进入正题: 序  顾名思义,这篇先介绍下QAxwidget来操作office和pdf ...

  5. 通过Jacob调用WPS将office文件转为PDF文件

    访问https://sourceforge.net/projects/jacob-project/ 想要调启Windows里的程序需要对应的dll库,下载之后解压 将符合你电脑的dll文件复制到jdk ...

  6. PHP实现office文件转PDF功能

            之前因为业务需要接触过在线浏览office文件,用过一些接口,例如:I DOC View(收费).Office Web 365(有免费版,详情可点击查看).online doc(有免费 ...

  7. python win32转pdf 横版_Python 小技巧之 Office 文件转 PDF

    文章来源于公众号:Python技术 作者:派森酱 在日常的生活工作中,难免需要用到一些 小Tip 来解决工作中遇到的小难题,今天的文章给大家安利一个方便快捷的小技巧,将 Office(doc/docx ...

  8. Libreoffice安装配置,office文件转PDF

    1.安装: 1.1.访问:Libreoffice官方下载地址 1.2点击下图所示链接下载 2.上传到服务器,进行解压 3.进入解压后的文件夹,有一个RPMS目录,进入RPMS文件夹 4.用yum来进行 ...

  9. OpenOffice+JodConverter实现Office文件到PDF的转换

    文章目录 1. OpenOffice 下载.安装.启动 2. JodConverter下载 3. 文件转化 4. 中文乱码 5. 解决中文乱码 1. OpenOffice 下载.安装.启动 openo ...

  10. office 文件在线协作编辑——解决方案1(基于sharepoint的二次开发)

    概述 office 文件在线协作编辑主要是指word.excel.ppt的多人在线协作编辑,实时同步的功能: 这里主要介绍解决方案之一--基于sharepoint的二次开发(还可以基于wopi实现)的 ...

最新文章

  1. 纯CSS3制作的圆角效果按钮菜单
  2. Python3.5入门到项目实战(104天课程)
  3. android开发 Gradle多渠道打包以及集成360加固
  4. 第二阶段冲刺10天 第一天
  5. NPOI导出Excel示例
  6. MPLS ××× 基本实验测试
  7. C++使用using与typedef定义别名
  8. Nginx禁止直接通过IP地址访问网站以及限制IP登陆某目录(关闭默认站点或空主机头)...
  9. openlayer中的投影
  10. Linux停服务器命令,使用linux的shutdown命令关闭服务器
  11. JDK和JRE安装与下载
  12. 航空公司客户价值分析完整版
  13. 优家益购——JavaWeb项目(Jsp+Servlet+MySQL+tomcat)
  14. 码云仓库第一次上传代码流程和git相关操作合集(持续更新)
  15. 达叔的游戏框架(二) 得到其他模块的方式
  16. php超链接打不开了,excel超链接无法打开怎么办
  17. unlink函数 与 remove函数
  18. 青藤 #44 比例简化
  19. 半监督学习笔记(四):熵最小化、代理变量
  20. 即构科技廖念波:构建产品矩阵,加快音视频技术全面开花

热门文章

  1. 网络投票专家投票计算_安全专家说在线投票是一个坏主意。 这就是为什么。
  2. c语言编程泰勒展开式计算,学习笔记:用c语言编写泰勒展开公式myexp()实现math.h.数学函数...
  3. 2022五一劳动节虾皮仓库物流放假安排
  4. 太阳方位角 太阳天顶角
  5. IllustratorCS5初学者必读(7):透明度调板
  6. vscode 程序员鼓励师_把软萌程序猿鼓励师装进VScode里?最强交互彩虹屁,GitHub2.5k星,爱上写代码...
  7. uwp浏览器java源码_uwp开发:webview模拟安卓浏览器
  8. 易优cms 后台登录报:验证码错误 Eyoucms快速入门
  9. 软考系统架构设计师学习笔记
  10. Blender建模汇总