自动创建Word(docx)
-
Word(docx)自动生成
- 介绍
- 目的
- 相关文章
- 执行环境
- 源代码
- UI实施
- docx创建的实现
简介
这是一篇有关Mac环境的文章,但步骤与Windows环境相同。请阅读并尝试与环境有关的部分。
目的
阅读完本文后,您将能够:
- 实施桌面应用
- 实现自动创建Word(docx)
呈现并输出JSON数据和Word(docx)模板。页面上输出多个数据项。
sample_data.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [ { "create_date": "令和元年 5月 1日", "to_company_name": "カレンダー株式会社", "to_company_department": "イヤホン本部", "relocation_date": "令和元年 7月 28日", "post_code": "123-4567", "new_address": "東京都港区サンプル1-2-3 ビルディング 45F", "new_phone_number": "1234-56-7890", "new_fax_number": "1234-56-7890" }, { "create_date": "2019年 5月 1日", "to_company_name": "冷暖房リモコン株式会社", "to_company_department": "ティッシュケース本部", "relocation_date": "2019年 7月 28日", "post_code": "987-6543", "new_address": "東京都港区サンプル9-8-7 ビルディング 65F", "new_phone_number": "0987-65-4321", "new_fax_number": "0987-65-4321" } ] |
第1/2页
第2/2页
相关文章
- tkinter-Tcl / Tk的Python接口
- docxtpl --PyPI
执行环境
<表格>
tr>
header>
<身体>
tr>
tr>
tr>
tr>
tbody>
table>
源代码
我认为,如果您在实际阅读实现内容和源代码的同时进行阅读,将会加深理解。请一定使用。
GitHub
UI实施
UI在Tkinter中实现。
Tkinter是适用于Windows,MacOS和Linux的跨平台GUI库。
app.py
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 69 70 71 72 73 74 75 76 77 | import os import tkinter as tk from tkinter import filedialog as fdialog from tkinter import messagebox as mdialog from model import Docx class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.create_widgets() def set_title(self): self.master.title('Create Docx') def set_menu_bar(self): self.menu_bar = tk.Menu(self.master) self.master.config(menu=self.menu_bar) file_menu = tk.Menu(self.menu_bar) file_menu.add_command(label='Exit', command=self.master.quit) self.menu_bar.add_cascade(label='File', menu=file_menu) def select_file(self, entry): entry.delete(0, tk.END) entry.insert(0, fdialog.askopenfilename(initialdir=os.getcwd())) def create_docx(self, json_url, template_url): if not os.path.exists(json_url) or not os.path.exists(template_url): mdialog.showerror('Error', 'Please select JSON and Template.') return docx = Docx(json_url=json_url, template_url=template_url) docx.render() def set_body(self): tk.Label(self.master, text='JSON:').grid(row=0, column=0) entry_json = tk.Entry(self.master) entry_json.grid(row=0, column=1, pady=5) tk.Button(self.master, text='Select...', command=lambda: self.select_file(entry_json)).grid(row=0, column=2) tk.Label(self.master, text='Template:').grid(row=1, column=0) entry_template = tk.Entry(self.master) entry_template.grid(row=1, column=1, pady=5) tk.Button(self.master, text='Select...', command=lambda: self.select_file(entry_template)).grid(row=1, column=2) tk.Button(self.master, text='Create', width=30, command=lambda: self.create_docx(entry_json.get(), entry_template.get())).grid(row=2, column=0, columnspan=3) def create_widgets(self): self.master.geometry() self.entry = tk.Entry(self.master) self.set_title() self.set_menu_bar() self.set_body() # fix tkinter bug start def fix_bug(): width_height = root.winfo_geometry().split('+')[0].split('x') width = int(width_height[0]) height = int(width_height[1]) root.geometry('{}x{}'.format(width+1, height+1)) # fix tkinter bug end if __name__ == '__main__': root = tk.Tk() app = Application(master=root) # fix tkinter bug start root.update() root.after(0, fix_bug) # fix tkinter bug end app.mainloop() |
docx创建
的实现
docx的创建是由docx tpl实现的。
docxtpl是一个呈现JSON数据和Word(docx)模板的库。
模型
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 | import cgi import json import os.path import re import sys import uuid from tkinter import messagebox as mdialog from docxtpl import DocxTemplate _illegal_unichrs = [(0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F), (0x7F, 0x84), (0x86, 0x9F), (0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF)] if sys.maxunicode >= 0x10000: # not narrow build _illegal_unichrs.extend([(0x1FFFE, 0x1FFFF), (0x2FFFE, 0x2FFFF), (0x3FFFE, 0x3FFFF), (0x4FFFE, 0x4FFFF), (0x5FFFE, 0x5FFFF), (0x6FFFE, 0x6FFFF), (0x7FFFE, 0x7FFFF), (0x8FFFE, 0x8FFFF), (0x9FFFE, 0x9FFFF), (0xAFFFE, 0xAFFFF), (0xBFFFE, 0xBFFFF), (0xCFFFE, 0xCFFFF), (0xDFFFE, 0xDFFFF), (0xEFFFE, 0xEFFFF), (0xFFFFE, 0xFFFFF), (0x10FFFE, 0x10FFFF)]) _illegal_ranges = ['%s-%s' % (chr(low), chr(high)) for (low, high) in _illegal_unichrs] _illegal_xml_chars_RE = re.compile(u'[%s]' % u''.join(_illegal_ranges)) class Docx(object): def __init__(self, json_url, template_url): self.json_url = json_url self.template_url = template_url def read_data(self): with open(self.json_url, 'r') as f: load_data = json.load(f) json_data = json.dumps(load_data) json_data = cgi.escape(json_data) json_data = json_data.replace('\n', '\\n') dict_data = json.loads(json_data) for d in dict_data: for k in d.keys(): try: d[k] = _illegal_xml_chars_RE.sub('', d[k]) except TypeError: pass return dict_data def render(self): dict_data = self.read_data() docx = DocxTemplate(self.template_url) docx.render({'applications': dict_data}) file_name = '{}.{}'.format(str(uuid.uuid4()), 'docx') save_dir = os.path.join(os.path.curdir, 'output') if not os.path.exists(save_dir): os.makedirs(save_dir) docx.save(os.path.join(save_dir, file_name)) mdialog.showinfo('Successful', 'Please check the output folder.') |