You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
6.3 KiB

import json
import sys
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
def get_command_argv_by_sys():
# 默认值-用于测试
template_path = "template.docx"
#template_path = "test.docx"
filename_path = "demo.docx"
datafile_path = "data.json"
#datafile_path = "data_1.json"
cycle = 0
# 读取参数
number = len(sys.argv)
if 2 == number:
template_path = sys.argv[1]
if 3 == number:
template_path = sys.argv[1]
filename_path = sys.argv[2]
if 4 == number:
template_path = sys.argv[1]
filename_path = sys.argv[2]
datafile_path = sys.argv[3]
if 5 == number:
template_path = sys.argv[1]
filename_path = sys.argv[2]
datafile_path = sys.argv[3]
cycle = sys.argv[4]
return template_path, filename_path, datafile_path,cycle
def read_data(filepath):
content = []
if filepath != "":
try:
with open(filepath, "r", encoding="utf-8") as file:
content = json.load(file)
finally:
return content
def replace(template_path, filename_path, data_json):
try:
document_file = Document(template_path)
except:
return 2
# 段落替换
for paragraph in document_file.paragraphs:
for datum in data_json:
if datum["key"] in paragraph.text:
if "text" == datum["type"]:
paragraph.text = paragraph.text.replace(datum["key"], datum["value"])
elif "picture" == datum["type"]:
paragraph.clear()
paragraph.add_run().add_picture(datum["value"], width=Inches(datum["width"]))
elif "number" == datum["type"]:
paragraph.text = paragraph.text.replace(datum["key"], str(datum["value"]))
# 表格替换
for table in document_file.tables:
# 字段
row = table.rows[0]
group = None
fields = []
for cell in row.cells:
split = cell.text.replace("}","").split(".")
group = split[0] + "}"
field = split[1]
fields.append(field.strip())
# 替换
for datum in data_json:
if datum["key"] in group:
rows = len(table.rows)
values = datum["value"]
for z in range(0, len(values)):
if z < rows:
row = table.rows[z]
else:
row = table.add_row()
item = values[z]
for i in range(0, len(fields)):
field = fields[i]
if item.get(field) is not None:
row.cells[i].text = str(item.get(field))
document_file.save(filename_path)
return 0
def foreach(template_path, filename_path, data_json):
try:
document_file = Document(template_path)
except:
return 2
placeholder = []
loop = False
i = 0
for paragraph in document_file.paragraphs:
text = paragraph.text
if "$[" == text:
loop = True
paragraph.clear()
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
continue
elif "]$" == text:
loop = False
paragraph.clear()
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
z = 0
for datum in data_json:
for item in placeholder:
key = item["paragraph"].text.replace("{", "").replace("}", "")
style = item["paragraph"].style
if key == datum["key"]:
if "text" == datum["type"]:
paragraph = document_file.add_paragraph(datum["value"], style=style)
paragraph._element.getparent().insert(z, paragraph._element)
elif "picture" == datum["type"]:
paragraph = document_file.add_paragraph(style=style)
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
paragraph.add_run().add_picture(datum["value"], width=Inches(datum["width"]))
paragraph._element.getparent().insert(z, paragraph._element)
elif "number" == datum["type"]:
paragraph = document_file.add_paragraph(str(datum["value"]), style=style)
paragraph._element.getparent().insert(z, paragraph._element)
# else:
# paragraph = document_file.add_paragraph(item["text"], style=style)
# paragraph._element.getparent().insert(z, paragraph._element)
z += 1
placeholder = []
if loop:
placeholder.append({"paragraph": paragraph, "key": text.replace("{", "").replace("}", ""), "style": paragraph.style,"text":text, "index": i})
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
else:
if text.startswith("{") and text.endswith("}"):
for datum in data_json:
if datum["key"] in text:
key = "{" + datum["key"] + "}"
if "text" == datum["type"]:
paragraph.text = paragraph.text.replace(key, datum["value"])
elif "picture" == datum["type"]:
paragraph.clear()
paragraph.add_run().add_picture(datum["value"], width=Inches(datum["width"]))
elif "number" == datum["type"]:
paragraph.text = paragraph.text.replace(key, str(datum["value"]))
i += 1
document_file.save(filename_path)
return 0
def main():
params = get_command_argv_by_sys()
[template, filename, datafile, cycle] = params
data = read_data(datafile)
if len(data) == 0:
return 1
else:
if cycle == 0:
return replace(template, filename, data)
else:
return foreach(template, filename, data)
if __name__ == '__main__':
print(main())