def set_para_omml(para, omml): ''' 将omml添加到段落中 :param para: :param omml: :return: ''' p = para._p # oMath = p.first_child_found_in("m:oMath") oMath = OxmlElement("m:oMath") p.append(oMath) oMath.extend(omml)
def insert_paragraph_after(self, paragraph, text=None, style=None): new_p = OxmlElement("w:p") paragraph._p.addnext(new_p) new_para = Paragraph(new_p, paragraph._parent) if text: new_para.add_run(text) if style is not None: new_para.style = style return new_para
def insert_paragraph_after(inparagraph, text=None, style=None): """Insert a new paragraph after the given paragraph.""" new_p = OxmlElement("w:p") inparagraph._p.addnext(new_p) new_para = Paragraph(new_p, inparagraph._parent) if text != None: new_para.style = template.styles[style] run = new_para.add_run(text) return new_para
def insert_paragraph_after(paragraph, text=None, style=None): """Insert a new paragraph after the given paragraph.""" new_p = OxmlElement("w:p") paragraph._p.addnext(new_p) new_para = Paragraph(new_p, paragraph._parent) if text: new_para.add_run(text) if style is not None: new_para.style = style return new_para
def set_cell_background(cell, fill): """ @fill: Specifies the color to be used for the background @color: Specifies the color to be used for any foreground pattern specified with the val attribute @val: Specifies the pattern to be used to lay the pattern color over the background color. """ from docx.oxml.shared import qn # feel free to move these out from docx.oxml.xmlchemy import OxmlElement cell_properties = cell._element.tcPr try: cell_shading = cell_properties.xpath('w:shd')[ 0] # in case there's already shading except IndexError: cell_shading = OxmlElement('w:shd') # add new w:shd element to it if fill: # set fill property, respecting namespace cell_shading.set(qn('w:fill'), fill) # finally extend cell props with shading element cell_properties.append(cell_shading)
def _set_cell_background(self, cell, fill, color=None, val=None): """ @fill: Specifies the color to be used for the background @color: Specifies the color to be used for any foreground pattern specified with the val attribute @val: Specifies the pattern to be used to lay the pattern color over the background color. """ cell_properties = cell._element.tcPr try: cell_shading = cell_properties.xpath('w:shd')[ 0] # in case there's already shading except IndexError: cell_shading = OxmlElement('w:shd') # add new w:shd element to it if fill: cell_shading.set(qn('w:fill'), fill) # set fill property, respecting namespace if color: pass # TODO if val: pass # TODO cell_properties.append( cell_shading) # finally extend cell props with shading element
def set_cell_border(cell, **kwargs): """ Set cell`s border Usage: set_cell_border( cell, top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"}, bottom={"sz": 12, "color": "#00FF00", "val": "single"}, left={"sz": 24, "val": "dashed", "shadow": "true"}, right={"sz": 12, "val": "dashed"}, ) """ tc = cell._tc tcPr = tc.get_or_add_tcPr() # 添加标签,如果不存在新增 tcBorders = tcPr.first_child_found_in("w:tcBorders") if tcBorders is None: tcBorders = OxmlElement('w:tcBorders') tcPr.append(tcBorders) # 所有所需的标签 for edge in ('left', 'top', 'right', 'bottom', 'insideH', 'insideV'): edge_data = kwargs.get(edge) if edge_data: tag = 'w:{}'.format(edge) # 添加单元格的子标签 element = tcBorders.find(qn(tag)) if element is None: element = OxmlElement(tag) tcBorders.append(element) # looks like order of attributes is important for key in ["sz", "val", "color", "space", "shadow"]: if key in edge_data: element.set(qn('w:{}'.format(key)), str(edge_data[key]))
def get_table(document, line, re_table): re_tr = re.compile("<tr>.*?</tr>", re.S | re.I) re_td = re.compile("<td.*?>.*?</td>", re.S | re.I) re_math = re.compile("<math.*?>.*?</math>", re.S | re.I) re_image = re.compile("<img.*?>", re.S | re.I) re_src = re.compile("src=(\".*?\")", re.S | re.I) table = re_table.findall(line) for tbl in table: rows = 0 cols = 0 td_array = [] trs = re_tr.findall(tbl) rows = len(trs) for tr in trs: tds = re_td.findall(tr) cols = len(tds) for td in tds: td = re.sub('<td.*?>', '', td) td = td.replace('</td>', '') td_array.append(td) i = 0 tbl_para = document.add_table(rows=rows, cols=cols, style='Table Grid') width = OxmlElement('w:tblW') width.set(qn('w:type'), 'pct') width.set(qn('w:w'), '{}'.format(cols * 500)) tbl_para._tblPr.append(width) tbl_para.alignment = WD_TABLE_ALIGNMENT.CENTER for r in tbl_para.rows: for c in r.cells: for para in c.paragraphs: para.alignment = WD_ALIGN_PARAGRAPH.CENTER if re_image.match(td_array[i]): img = re_image.match(td_array[i]) src = re_src.match(str(img)).replace('http://', '') para.add_run().add_picture(src) elif re_math.match(td_array[i]): math = re_math.match(td_array[i]) omml = mathml2omml_lbj(math) root = ET.fromstring(str(omml)) set_para_omml(para, root) # 将omml公式按xml节点的形式添加到当前段落的标签下 else: para.add_run(td_array[i]) i += 1
def writeword(gutter, secrecy, main_title, sub_title, info_bar, testee, score_bar, note, winding, group, score_area, fmt, size, usage): model_path = r'C:\Users\j20687\Desktop\model.docx' # t0 = int(round(time.time() * 1000)) # tmp_path = '/tmp/%d.docx' % t0 # os.system('cp %s %s' % (model_path, tmp_path)) document = Document(model_path) # 设置整个文档的默认字体 microsoft_font = u'宋体' # u 表示后面的字符串以 Unicode 格式进行编码 black_font = u'黑体' number_font = 'Times New Roman' area = qn('w:eastAsia') document.styles['Normal'].font.name = microsoft_font document.styles['Normal'].font.size = Pt(10.5) document.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0) document.styles['Normal']._element.rPr.rFonts.set(area, number_font) # 指定段落样式 styles = document.styles s = styles.add_style('paragraph', WD_STYLE_TYPE.PARAGRAPH) s.font.name = microsoft_font s.font.size = Pt(10.5) s.font.color.rgb = RGBColor(0, 0, 0) s.paragraph_format.line_spacing = Pt(0) # 行距值 s.paragraph_format.space_before = Pt(0) # 段前距 s.paragraph_format.space_after = Pt(0) # 段后距 s.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE # 行间距,单倍行距 s._element.rPr.rFonts.set(area, number_font) # 除中文外其它文字 使用的字体 ,备选项 # 设置页眉 # header = document.sections[0].header # h_para = header.paragraphs[0] # h_para.alignment = WD_ALIGN_PARAGRAPH.CENTER # run = h_para.add_run("本卷由系统自动生成,请仔细校对后使用") # run.font.size = Pt(9) types = ['一、', '二、', '三、', '四、', '五、', '六、', '七、', '八、', '九、', '十、'] if gutter == 1: pass if secrecy: run = document.add_paragraph() run.style = s p = run.add_run(secrecy) p.bold = True font = p.font font.name = black_font font.color.rgb = RGBColor(0, 0, 0) font.size = Pt(10.5) if main_title: run = document.add_paragraph() run.style = s p = run.add_run(main_title) p.bold = True font = p.font font.name = black_font font.color.rgb = RGBColor(0, 0, 0) font.size = Pt(15) run.alignment = WD_ALIGN_PARAGRAPH.CENTER if sub_title: run = document.add_paragraph() run.style = s p1 = run.add_run(sub_title) p1.bold = True font1 = p1.font font1.name = black_font font1.color.rgb = RGBColor(0, 0, 0) font1.size = Pt(18) run.alignment = WD_ALIGN_PARAGRAPH.CENTER if info_bar: p = document.add_paragraph(info_bar) p.style = s p.alignment = WD_ALIGN_PARAGRAPH.CENTER if testee: p = document.add_paragraph(testee) p.style = s p.alignment = WD_ALIGN_PARAGRAPH.CENTER if score_bar: rows = 2 cols = len(group) + 2 table = document.add_table(rows=rows, cols=cols, style='Table Grid') width = OxmlElement('w:tblW') width.set(qn('w:type'), 'pct') width.set(qn('w:w'), '{}'.format(cols * 500)) table._tblPr.append(width) # 指定表格宽度 table.alignment = WD_TABLE_ALIGNMENT.CENTER for r in table.rows: for c in r.cells: for para in c.paragraphs: para.alignment = WD_ALIGN_PARAGRAPH.CENTER cell1 = table.rows[0].cells cell1[0].paragraphs[0].add_run('题号') cell1[-1].paragraphs[0].add_run('总分') for i in range(1, cols - 1): cell1[i].paragraphs[0].add_run(types[i - 1]) cell2 = table.rows[1].cells cell2[0].paragraphs[0].add_run('得分') if note: p = document.add_paragraph() p.style = s run = p.add_run('注意事项:') run.add_break() re_split = re.compile("<.*?>", re.S | re.I) line = re.sub(re_split, '**', note) lines = line.split('**') for ll in lines: run = p.add_run(ll) run.add_break() if winding: i = 0 for corner in winding: p = document.add_paragraph() p.style = s run = p.add_run(corner) run.bold = True run.font.size = Pt(12) p.alignment = WD_ALIGN_PARAGRAPH.CENTER if group: for type in group: if type['exam_winding']: name = type['exam_winding']['name'] or "" if name == corner: ques_type = type['name'] # 每一种题型 ques_type = types[i] + str(ques_type) i += 1 questiongroup(type, score_area, usage, ques_type, document, s) # 试题主体 else: i = 0 for type in group: ques_type = type['name'] # 每一种题型 ques_type = types[i] + str(ques_type) i += 1 questiongroup(type, score_area, usage, ques_type, document, s) # 试题主体 # if load_code == 2: # document.add_page_break() # 换页 # p = document.add_paragraph() # p.style = s # p.add_run('参考答案').bold = True # p.alignment = WD_ALIGN_PARAGRAPH.CENTER # answergroup(group, document, s) t1 = int(round(time.time() * 1000)) # docx = '/tmp/%d.%s' % (t1, 'docx') docx = r'C:\Users\j20687\Desktop\%d.%s' % (t1, 'docx') document.save(docx) # if fmt == 1: # doc_path = '/tmp/%d.%s' % (t1, 'doc') # os.system('soffice --headless --invisible --convert-to doc %s --outdir /tmp' % docx) # return doc_path # elif fmt == 2: # return docx # else: # pdf_path = '/tmp/%d.%s' % (t1, 'pdf') # os.system('soffice --headless --invisible --convert-to pdf %s --outdir /tmp' % docx) # return pdf_path return docx
def questiongroup(type, score_area, usage, ques_type, document, s): if score_area == 1: table = document.add_table(rows=2, cols=3, style='Table Grid') width = OxmlElement('w:tblW') width.set(qn('w:type'), 'pct') width.set(qn('w:w'), '{}'.format(3 * 500)) table._tblPr.append(width) for r in table.rows: for c in r.cells: for para in c.paragraphs: para.alignment = WD_ALIGN_PARAGRAPH.CENTER set_cell_border( table.cell(0, 2), top={ "sz": 0, "val": "single", "color": "#FFFFFF" }, bottom={ "sz": 0, "color": "#FFFFFF", "val": "single" }, left={ "sz": 0, "val": "single", "color": "#000000" }, right={ "sz": 0, "val": "single", "color": "#FFFFFF", }, ) set_cell_border( table.cell(1, 2), top={ "sz": 0, "val": "single", "color": "#FFFFFF" }, bottom={ "sz": 0, "color": "#FFFFFF", "val": "single" }, left={ "sz": 0, "val": "single", "color": "#000000" }, right={ "sz": 0, "val": "single", "color": "#FFFFFF", }, ) p = table.cell(0, 2).merge(table.cell(1, 2)).paragraphs[0] p.add_run().add_break() p.add_run('%s' % str(ques_type)) table.cell(0, 0).paragraphs[0].add_run('评卷人') table.cell(0, 1).paragraphs[0].add_run('得分') else: p = document.add_paragraph() p.add_run('%s' % str(ques_type)).bold = True p.paragraph_format.space_before = Pt(8) # 段前距 p.paragraph_format.space_after = Pt(8) # 段后距 questions = type['exam_questions'] # 一个题型的所有题 for question in questions: # 每一道题 content = question['question']['content']['content'].replace('<p>', '').replace(' ', ' ') \ if question['question']['content']['content'] else "" option = question['question']['options'] or "" opt_line = question['question']['option_line'] or 0 answer = question['question']['answer'].replace('<p>', '').replace(' ', ' ') \ if question['question']['answer'] else "" analysis = question['question']['explain'].replace('<p>', '').replace(' ', ' ') \ if question['question']['explain'] else "" if usage == 1: getline(content, document, s) if option or opt_line == 0: getoption(option, opt_line, document, s) p1 = document.add_paragraph() p1.style = s p1.add_run("【答案】").font.color.rgb = RGBColor(0x42, 0x24, 0xE9) getline(answer, document, s) p2 = document.add_paragraph() p2.style = s p2.add_run("【解析】").font.color.rgb = RGBColor(0x42, 0x24, 0xE9) getline(analysis, document, s) else: getline(content, document, s) if option or opt_line == 0: getoption(option, opt_line, document, s)
def StartBtn(): document = Document() section = document.sections[0] style = document.styles['Normal'] font = style.font header = section.header header.is_linked_to_previous = False paragraph = header.paragraphs[0] font.size = Pt(35) paragraph.text = TextVal.get() paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER sec_pr = document.sections[0]._sectPr # pg_borders = OxmlElement('w:pgBorders') pg_borders.set(qn('w:offsetFrom'), 'page') for border_name in ( 'top', 'left', 'bottom', 'right', ): # set all borders border_el = OxmlElement(f'w:{border_name}') border_el.set(qn('w:val'), 'single') #single line border_el.set(qn('w:sz'), '24') # for meaning of remaining attrs please look docs border_el.set(qn('w:space'), '26') border_el.set(qn('w:color'), 'blue') pg_borders.append(border_el) # register single border to border el sec_pr.append(pg_borders) # document.add_paragraph( 'Inspection File is ready',style="Caption") paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER global size1, size2 real = n.get() if (real == 2): sectPr = section._sectPr cols = sectPr.xpath('./w:cols')[0] cols.set(qn('w:num'), '1') size1 = 6.2362204724 size2 = 4.0787402 elif (real == 3): size1 = 5.354331 size2 = 2.771654 elif (real == 6): sectPr = section._sectPr cols = sectPr.xpath('./w:cols')[0] cols.set(qn('w:num'), '2') size1 = 2.75591 size2 = 2.75591 for file in glob.glob('*.%s' % ext): img = Image.open(file) img = img.resize((1024, 768)) img.save(file) paragraph_format = paragraph.paragraph_format p = document.add_paragraph() r = p.add_run() r.add_picture(file, width=Inches(size1), height=Inches(size2)) last_paragraph = document.paragraphs[-1] last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER filenam = TextVal.get() document.save(filenam + ".docx") print(real) messagebox.showinfo("COMPRESS & SAVE ", "YOUR DOCUMENT IS READY") print('Done')
def config_borders(document: Document): section_properties = document.sections[0]._sectPr page_borders = OxmlElement('w:pgBorders') page_borders.set(qn('w:offsetFrom'), 'page') for border_name in ('top', 'bottom'): border = OxmlElement(f'w:{border_name}') border.set(qn('w:val'), 'single') border.set(qn('w:sz'), '8') border.set(qn('w:space'), '10') border.set(qn('w:color'), 'auto') page_borders.append(border) for border_name in ('right', 'left'): border = OxmlElement(f'w:{border_name}') border.set(qn('w:val'), 'single') border.set(qn('w:sz'), '8') border.set(qn('w:space'), '15') border.set(qn('w:color'), 'auto') page_borders.append(border) section_properties.append(page_borders) return
def create_element(self, name): return OxmlElement(name)