python操作word文档(python-docx)
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python操作word文档(python-docx)相关的知识,希望对你有一定的参考价值。
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文件打开