doc文件转docx文件

doc文件转docx文件

众所周知,python的word文件解析包python-docx是无法直接解析doc文件的,但是在windows系统下有一个包pypiwin32,利用这个包可以将doc文件转换为docx文件,但是使用起来有两个局限:

  1. Linux系统中没有这个包;
  2. 这个包必须通过显示的文件保存操作来进行转换(没有办法仅通过文件二进制流操作)。

这两个包的安装:

1
2
pip install python-docx
pip install pypiwin32

所以可以使用这个包结合flask将转换程序作为一个服务部署在windows服务器上,后续可以方便的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# coding=utf-8
import json
import logging
import os
import pythoncom
import random
from flask import Flask, request
from win32com import client as wc

app = Flask(__name__)


def doc2docx_win(doc_content):
"""
windows环境下可以调用此方法将doc文件转换为docx文件
:return: docx_content
"""
random_name = random.random() # 使用一个随机的文件名称,避免多线程同时操作一个文件
# 路径自行设定
doc_path = rf'doc2docx/temp_{random_name}.doc'
docx_path = rf'doc2docx/temp_{random_name}.docx'
# if os.path.exists(doc_path): # 如果在服务重启之前,意外终止导致temp文件未能删除,使用os.remove也是删不掉的
# os.remove(doc_path)
# if os.path.exists(docx_path):
# os.remove(docx_path)

pythoncom.CoInitialize() # 多线程/多进程使用win32需要先执行这一步
w = wc.Dispatch('Word.Application')

# 先把二进制保存为文件
with open(doc_path, 'wb') as fw:
fw.write(doc_content)
try:
doc = w.Documents.Open(doc_path) # 有些传进来的文件可能就是损坏的或者下载的不完整的
except Exception:
# 如果文件有问题,要把保存的这个文件删除,否则影响后续的操作
os.remove(doc_path)
return ''
doc.SaveAs(docx_path, 16) # 保存为docx文件

doc.Close() # 只有先关闭doc/docx文件才能删除
w.Quit() # 关闭为win32对象(有时候把word关了可能后续处理会出错,但是作为服务这个一定要关闭,代价是会变慢,但是不关闭服务调用几次之后就会异常)
# pythoncom.CoUninitialize() # 释放资源

with open(docx_path, 'rb') as fr:
docx_content = fr.read()
os.remove(doc_path)
os.remove(docx_path)
return docx_content


@app.route('/doc2docx', methods=['POST'])
def reg():
binary_content = request.get_data()
for _ in range(3):
try:
docx_content = doc2docx_win(binary_content)
except RuntimeError as _e:
logging.info(_e)
except Exception as _e:
logging.exception(_e)
else:
return docx_content
return ''


if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

将上面的代码保存为py文件,之后修改后缀名为pyw,直接双击点击即可后台启动该程序。