python操作word文档(python-docx)

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python操作word文档(python-docx)相关的知识,希望对你有一定的参考价值。

写这篇博客源于博友的提问,将介绍如何使用python-docx操作word文档。python-docx不支持表格内文本水平居中,可以考虑使用itextpdf,生成pdf的表格然后在转回word。
itexpdf7支持的样式都比较灵活和多样。

1. 效果图

1. 1 python-docx效果图

先使用55表格,然后在行中分别对某些cell在添加一个小的12的table实现

直接用5*9表格,标头部分列cell进行合并,效果图如下:

python-docx不够灵活,没法居中等;但自带了比较多的样式:
Light Shading如下:

Light List样式如下:
Light Grid如下:
Medium Shading如下:

Medium List如下:

Dark List效果图如下:

Colorful Shading效果图如下:

1.2 itextpdf7效果图

2. 安装

前提依赖:

  • Python 2.6, 2.7, 3.3, or 3.4
  • lxml >= 2.3.2

pip安装python-docx:

pip install python-docx

3. 源代码

3.1 python-docx源码

# python操作doxc demo类

from docx import Document
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

document = Document()

document.add_heading('Document Title', 0)

p = document.add_paragraph('A plain paragraph having some ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True
print(p.style.font.size)
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

document.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='Intense Quote')

document.add_paragraph(
    'first item in unordered list', style='List Bullet'
)
document.add_paragraph(
    'first item in ordered list', style='List Number'
)

record_score = (
    ('学习目标-1', '', '', '21', '12.59', '', '', '21', '12.59'),
    ('学习目标-2', '', '', '16', '10.88', '14', '11.25', '30', '22.13'),
    ('学习目标-3', '17', '14.11', '', '', '32', '21.95', '49', '36.66')
)

# 获取文档自带的所有styles
styles = document.styles

table = document.add_table(rows=2, cols=5, style=styles['Table Grid'])
table.alignment = WD_TABLE_ALIGNMENT.CENTER
hdr_cells = table.rows[0].cells
hdr_cells[1].text = '2.1'
hdr_cells[2].text = '3.2'
hdr_cells[3].text = '7.4'
hdr_cells[4].text = '期末成绩'
hdr_cells = table.rows[1].cells
for i in range(5):
    if (i == 0):
        continue
    t1 = hdr_cells[i].add_table(0, 2)
    t1_cells = t1.add_row().cells
    t1_cells[0].text = '分值'
    t1_cells[1].text = '平均分'
for xxmb, l1, l2, l3, l4, l5, l6, l7, l8 in record_score:
    row_cells = table.add_row().cells
    l = [l1, l2, l3, l4, l5, l6, l7, l8]
    for i in range(5):
        if (i == 0):
            row_cells[i].text = xxmb
            continue
        t2 = row_cells[i].add_table(0, 2)
        t2_cells = t2.add_row().cells
        t2_cells[0].text = l[(i - 1) * 2]
        t2_cells[1].text = l[(i - 1) * 2 + 1]

p = document.add_paragraph('\\n\\n\\n\\n')
table = document.add_table(rows=2, cols=9, style=styles['Table Grid'])
print(table.style.font.size)
# table.style.font.size = int(304800//3.8)
table.style.font.size = 80000
print(table.style.font.size)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
hdr_cells = table.rows[0].cells
header = ['', '2.1', '3.2', '7.4', '期末成绩']
for i in range(5):
    if (i == 0):
        print(hdr_cells[i].width)
        continue
    tc = hdr_cells[i * 2 - 1].merge(hdr_cells[i * 2])
    tc.text = header[i]

row_cells = table.rows[1].cells
for i in range(5):
    if (i == 0):
        continue
    row_cells[i * 2 - 1].text = '分值'
    row_cells[i * 2].text = '平均分'

for i, l in enumerate(record_score):
    row_cells = table.add_row().cells
    for j in range(9):
        row_cells[j].text = l[j]

p = document.add_paragraph('\\n\\n\\n\\n')

for ii, style in enumerate(styles):
    if (not '_TableStyle' in str(style)):
        continue
    p = document.add_paragraph('\\n' + str(ii) + " " + str(style))
    table = document.add_table(rows=2, cols=9, style=style)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    hdr_cells = table.rows[0].cells
    header = ['', '2.1', '3.2', '7.4', '期末成绩']
    for i in range(5):
        if (i == 0):
            continue
        tc = hdr_cells[i * 2 - 1].merge(hdr_cells[i * 2])
        tc.text = header[i]

    row_cells = table.rows[1].cells
    for i in range(5):
        if (i == 0):
            continue
        row_cells[i * 2 - 1].text = '分值'
        row_cells[i * 2].text = '平均分'

    for i, l in enumerate(record_score):
        row_cells = table.add_row().cells
        for j in range(9):
            row_cells[j].text = l[j]

document.save('images/demo_merge_2.docx')

3.2 itextpdf源码

package com.itextpdf.samples.sandbox.tables;

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.*;
import com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class SimpleTable10_ {
    public static final String DEST = "./target/sandbox/tables/simple_table10_.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new SimpleTable10_().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);

        Table table = new Table(UnitValue.createPercentArray(9)).useAllAvailableWidth();
        table.setHorizontalAlignment(HorizontalAlignment.CENTER);
        table.setVerticalAlignment(VerticalAlignment.MIDDLE);

        // 首行
//        table.addCell("").addCell(new Cell(1, 2).add(new Paragraph("2.1").setHorizontalAlignment(HorizontalAlignment.CENTER))
//                .setVerticalAlignment(VerticalAlignment.MIDDLE).setHorizontalAlignment(HorizontalAlignment.CENTER));
//        table.addCell(new Cell(1, 2).add(new Paragraph("3.2")));
//        table.addCell(new Cell(1, 2).add(new Paragraph("7.4")));
//        table.addCell(new Cell(1, 2).add(new Paragraph("期末成绩dd")));
        String[] header = new String[]{"", "2.1", "3.2", "7.4", "期末成绩dd"};
        for (int i = 0; i < 5; i++) {
            if (i == 0) {
                table.addCell("");
                continue;
            }
            Cell cell0 = new Cell(1, 2);
            cell0.setHeight(20);
            cell0.setNextRenderer(new SimpleTable10_.PositionRenderer(cell0, 0.5f, 0.5f,
                    header[i], TextAlignment.CENTER));
            table.addCell(cell0);
        }

        // 第2行
//        table.addCell("").addCell("分数grade").addCell("成绩score")
//                .addCell("分数grade").addCell("成绩score")
//                .addCell("分数grade").addCell("成绩score")
//                .addCell("分数grade").addCell("成绩score").setHorizontalAlignment(HorizontalAlignment.CENTER);
        for (int i = 0; i < 5; i++) {
            if (i == 0) {
                table.addCell("");
                continue;
            }
            Cell cell1 = new Cell();
            cell1.setHeight(20);
            cell1.setNextRenderer(new SimpleTable10_.PositionRenderer(cell1, 0.5f, 0.5f,
                    "分数grade", TextAlignment.CENTER));
            table.addCell(cell1);
            Cell cell2 = new Cell();
            cell2.setHeight(20);
            cell2.setNextRenderer(new SimpleTable10_.PositionRenderer(cell2, 0.5f, 0.5f,
                    "成绩score", TextAlignment.CENTER));
            table.addCell(cell2);
        }

        Cell sn = new Cell(3, 1).add(new Paragraph("学习目标-1\\n学习目标-2\\n学习目标-3"));
//        sn.setBackgroundColor(ColorConstants.YELLOW);
        table.addCell(sn);

        List<String> stringList = new ArrayList<>();
        stringList.add("\\"\\", \\"\\", \\"21\\", \\"12.59\\", \\"\\", \\"\\", \\"21\\", \\"12.59\\"," +
                "\\"\\", \\"\\", \\"16\\", \\"10.88\\", \\"14\\", \\"11.25\\", \\"20\\", \\"22.13\\"," +
                "\\"17\\", \\"14.11\\", \\"\\", \\"\\", \\"32\\", \\"21.95\\", \\"49\\", \\"36.66\\"");
        String[] scores = stringList.get(0).split(",");

        for (int i = 0; i < 24; i++) {
            Cell cell7 = new Cell();
            cell7.setHeight(20);
            cell7.setNextRenderer(new SimpleTable10_.PositionRenderer(cell7, 0.5f, 0.5f,
                    scores[i].replaceAll("\\"", ""), TextAlignment.CENTER));
            table.addCell(cell7);
//            table.addCell(scores[i].replaceAll("\\"", "")).setHorizontalAlignment(HorizontalAlignment.CENTER);
        }

        doc.add(table);

        doc.close();
    }

    private static class PositionRenderer extends CellRenderer {
        private String content;
        private TextAlignment alignment;
        private float wPct;
        private float hPct;

        public PositionRenderer(Cell modelElement, float wPct, float hPct,
                                String content, TextAlignment alignment) {
            super(modelElement);
            this.content = content;
            this.alignment = alignment;
            this.wPct = wPct;
            this.hPct = hPct;
        }

        // If a renderer overflows on the next area, iText uses #getNextRenderer() method to create a new renderer for the overflow part.
        // If #getNextRenderer() isn't overridden, the default method will be used and thus the default rather than the custom
        // renderer will be created
        @Override
        public IRenderer getNextRenderer() {
            return new SimpleTable10_.PositionRenderer((Cell) modelElement, wPct, hPct, content, alignment);
        }

        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
//            drawContext.getCanvas().addXObjectFittedIntoRectangle(img.getXObject(), getOccupiedAreaBBox());
            drawContext.getCanvas().stroke();

            UnitValue fontSizeUV = getPropertyAsUnitValue(Property.FONT_SIZE);
            Python-doc rst文件打开

python操作word文档表格

67.python操作word文档

python 操作 word 文档,使用 python-docx 操作 word docx 文档

python操作word文档(python-docx)

Python如何操作word文档,Python-docx类库的使用