一、phpword处理word文件
phpword的模板处理
1、markdown内容替换
markdown简单格式内容替换word变量
word模版变量
${block_name}
${markdown}
${/block_name}
$markdownText = "# 标题1\n内容\n内容2\n![image](http://localhost/1.png)";
# 将mardown数据转换成html
$parsedown = new Parsedown();
$htmlString = $parsedown->text($markdownText);
# 忽略不清除的html标签 多个示例 <a><img><p>
$allowedTags = '<img>';
# 清除html的标签
$plainText = strip_tags($htmlString, $allowedTags);
$plainTextArr = explode("\n",$plainText);
$lists = [];
foreach($plainTextArr as $htmlString) {
$matches = [];
preg_match_all('/<img[^>]*src="([^"]*)"[^>]*>/i', $htmlString, $matches);
if ($matches[1]) {
$lists[] = ['type' => 'img', 'value'=>current($matches[1])];
continue;
}
$matches = [];
preg_match_all('/<h1>(.*?)<\/h1>/is', $htmlString, $matches);
if ($matches[1]) {
$lists[] = ['type' => 'h1', 'value'=>current($matches[1])];
continue;
}
$lists[] = ['type' => 'text', 'value'=>$htmlString];
}
$plateform = new TemplateProcessor('xxx.docx');
$plateform->cloneBlock('block_name',count($lists),true,true);
foreach ($lists as $k => $list) {
if ($list['type'] == 'img') {
$img = $list['value'];
# 读取图片详情并设定宽高
$imgInfo = getimagesize($img);
if ($imgInfo[0] > $imgInfo[1]) {
$maxWidth = '14'; # 换算比例定宽
$width = ($imgInfo[0] > $maxWidth ? $maxWidth : $imgInfo[0]).'cm';
$height = ($imgInfo[0] > $maxWidth ? number_format(($imgInfo[1]*($maxWidth/$imgInfo[0])),2,'.','') : $imgInfo[1]).'cm';
} else {
$maxHeight = '10'; # 换算比例定高
$height = ($imgInfo[1] > $maxHeight ? $maxHeight : $imgInfo[1]).'cm';
$width = ($imgInfo[1] > $maxHeight ? number_format(($imgInfo[0]*($maxHeight/$imgInfo[1])),2,'.','') : $imgInfo[0]).'cm';
}
# 改变图片变量段落样式
$paragragph = new Paragraph();
$paragragph->setAlignment(Jc::CENTER);
$inline = new TextRun($paragragph);
$inline->addText('${'.'markdown#'.($k+1).'}');
$plateform->setComplexBlock('markdown#'.($k+1), $inline);
# 替换变量为图片
$plateform->setImageValue('markdown#'.($k+1),array('path' => $list['value'], 'width' => $width, 'height' => $height, 'ratio' => false));
} elseif ($list['type'] == 'h1') {
# 这里仅做了加粗处理
$inline = new TextRun();
$inline->addText($list['value'], ['bold' => true]);
$this->template->setComplexValue('markdown#'.($k+1), $inline);
} else {
$plateform->setValue('markdown#'.($k+1),$list['value']);
}
}
$plateform->saveAs(xxx.docx);
二、python刷新word目录
* 此功能需要使用windows系统和Microsoft Office
1、环境搭建
- 安装windows版本python
- 安装扩展1:pip install Flask
- 安装扩展2:pip install pywin32
2、刷新word脚本
文件名:change.py
import win32com.client
import sys
def change(filepath):
word = win32com.client.DispatchEx("Word.Application")
doc = word.Documents.Open(filepath)
doc.TablesOfContents(1).Update()
doc.Close(SaveChanges=True)
word.Quit()
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python change.py <filepath>")
else:
print(sys.argv)
filepath = sys.argv[1]
change(filepath)
3、Web服务接口
文件名:upload.py或upload.pyw。
两者区别:
.py需要在命令行窗口使用python upload.py命令启动web服务,关闭命令行窗口则服务失效,调试阶段方便查看错误日志
.pyw只需要双击upload.pyw文件即可启动web服务
from flask import Flask, request, jsonify, send_file
import os
import subprocess
import win32com.client
import sys
import logging
app = Flask(__name__)
# 鉴权验证 自行实现复杂鉴权
UPLOADTOKEN = '!@#456&*1'
# 获取当前目录
current_script_path = os.path.abspath(__file__)
win_dir = os.path.dirname(current_script_path)
# 日志文件
requests_log = win_dir+'app_requests.log'
logging.basicConfig(filename='app_requests.log', level=logging.INFO)
logging.basicConfig(filename='app_requests.log', level=logging.ERROR)
@app.route('/upload', methods=['POST'])
def upload_file():
if UPLOADTOKEN != request.form['token']:
return jsonify({"error": "Token verification failed"}), 500
"""
接收上传文件的接口
"""
if 'file' not in request.files:
return jsonify({"error": "No file part"}), 400
file = request.files['file']
if file.filename == '':
return jsonify({"error": "No selected file"}), 400
if file and file.filename.endswith('.docx'):
file_path = os.path.join("uploads", file.filename)
file.save(file_path)
win_file_path = win_dir+'\\'+file_path
subprocess.check_output([sys.executable, win_dir+'\\change.py', win_file_path], text=True)
# 响应处理后的Word文件给客户端,并设置为下载
return send_file(file_path, as_attachment=True, download_name=file.filename)
if __name__ == '__main__':
# 确保uploads目录存在
os.makedirs("uploads", exist_ok=True)
app.run(host='0.0.0.0', port=5000) # 注意,这将使得应用监听所有IP地址的5000端口