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.
		
		
		
		
		
			
		
			
				
					
					
						
							116 lines
						
					
					
						
							3.5 KiB
						
					
					
				
			
		
		
	
	
							116 lines
						
					
					
						
							3.5 KiB
						
					
					
				import json
 | 
						|
import sys
 | 
						|
from copy import deepcopy
 | 
						|
from docx import Document
 | 
						|
from docx.shared import Inches
 | 
						|
 | 
						|
def get_command_argv_by_sys():
 | 
						|
    # 默认值-用于测试
 | 
						|
    template_path = "template.docx"
 | 
						|
    filename_path = "demo.docx"
 | 
						|
    datafile_path = "data.json"
 | 
						|
 | 
						|
    # 读取参数
 | 
						|
    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]
 | 
						|
 | 
						|
    return template_path, filename_path, datafile_path
 | 
						|
 | 
						|
 | 
						|
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"]))
 | 
						|
                elif "list" == datum["type"]:
 | 
						|
                    p = paragraph._p
 | 
						|
                    index = list(document_file.element.body.iterchildren()).index(p)
 | 
						|
                    key = datum["key"]
 | 
						|
                    values = datum["value"]
 | 
						|
                    for i in range(0,len(values)):
 | 
						|
                        paragraph = deepcopy(p)
 | 
						|
                        document_file.element.body.insert(index + i + 1, paragraph)
 | 
						|
                    paragraph.clear()
 | 
						|
 | 
						|
                    for i in range(0, len(values)):
 | 
						|
                        val = values[i]
 | 
						|
                        paragraph = document_file.paragraphs[index - 1 + i]
 | 
						|
                        paragraph.text = paragraph.text.replace(key, str(val))
 | 
						|
 | 
						|
 | 
						|
    # 表格替换
 | 
						|
    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 main():
 | 
						|
    params = get_command_argv_by_sys()
 | 
						|
    [template, filename, datafile] = params
 | 
						|
    data = read_data(datafile)
 | 
						|
    if len(data) == 0:
 | 
						|
        return 1
 | 
						|
    else:
 | 
						|
        return replace(template, filename, data)
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    print(main())
 | 
						|
 |