💻 Python和Go代码示例
详细讲解如何使用Python和Go语言处理DOCX文件
Python处理DOCX文件
使用python-docx库轻松操作DOCX文件
推荐
1. 安装python-docx库
# 使用pip安装 pip install python-docx # 或者使用conda conda install -c conda-forge python-docx
2. 创建新文档
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# 创建新文档
doc = Document()
# 添加标题
doc.add_heading('欢迎使用python-docx', level=1)
# 添加段落
paragraph = doc.add_paragraph('这是一个普通的段落文本。')
# 添加带格式的段落
formatted_para = doc.add_paragraph()
run = formatted_para.add_run('这是')
run.bold = True
run.add_run('加粗的')
run.italic = True
run.add_run('和斜体的文本。')
# 设置字体大小和颜色
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(255, 0, 0)
# 添加标题
doc.add_heading('示例表格', level=2)
# 添加表格
table = doc.add_table(rows=3, cols=3)
table.style = 'Light Grid Accent 1'
# 设置表头
header_cells = table.rows[0].cells
header_cells[0].text = '姓名'
header_cells[1].text = '年龄'
header_cells[2].text = '职业'
# 填充数据
table.rows[1].cells[0].text = '张三'
table.rows[1].cells[1].text = '25'
table.rows[1].cells[2].text = '工程师'
table.rows[2].cells[0].text = '李四'
table.rows[2].cells[1].text = '30'
table.rows[2].cells[2].text = '设计师'
# 添加图片
doc.add_heading('添加图片', level=2)
doc.add_picture('image.png', width=Inches(4.0))
# 保存文档
doc.save('example.docx')
print('文档创建成功!')
3. 读取文档内容
from docx import Document
# 打开现有文档
doc = Document('example.docx')
# 读取所有段落
print('=== 所有段落 ===')
for para in doc.paragraphs:
print(para.text)
# 读取所有表格
print('\n=== 所有表格 ===')
for table in doc.tables:
for row in table.rows:
row_data = [cell.text for cell in row.cells]
print(row_data)
# 读取特定样式的内容
print('\n=== 所有标题 ===')
for para in doc.paragraphs:
if para.style.name.startswith('Heading'):
print(f'{para.style.name}: {para.text}')
# 获取文档属性
print('\n=== 文档属性 ===')
core_props = doc.core_properties
print(f'标题: {core_props.title}')
print(f'作者: {core_props.author}')
print(f'创建时间: {core_props.created}')
print(f'修改时间: {core_props.modified}')
4. 修改现有文档
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# 打开现有文档
doc = Document('example.docx')
# 修改段落文本
for para in doc.paragraphs:
if '欢迎使用' in para.text:
# 清除原有内容
para.clear()
# 添加新文本
run = para.add_run('欢迎修改文档')
run.bold = True
run.font.color.rgb = RGBColor(0, 102, 204)
# 添加新段落
new_para = doc.add_paragraph('这是新添加的段落', style='Intense Quote')
# 修改表格数据
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
if '张三' in cell.text:
cell.text = '王五'
# 修改文档属性
doc.core_properties.title = '修改后的文档'
doc.core_properties.author = '新作者'
# 保存修改
doc.save('modified.docx')
print('文档修改完成!')
5. 高级功能
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
# 创建文档
doc = Document()
# 自定义样式
styles = doc.styles
style = styles.add_style('CustomStyle', 1) # 1表示段落样式
style.font.name = '微软雅黑'
style.font.size = Pt(12)
style.font.color.rgb = RGBColor(51, 51, 51)
style.paragraph_format.line_spacing = 1.5
# 添加分页符
doc.add_page_break()
# 设置页眉
section = doc.sections[0]
header = section.header
header_para = header.paragraphs[0]
header_para.text = "这是页眉"
header_para.style = doc.styles['Header']
# 设置页脚
footer = section.footer
footer_para = footer.paragraphs[0]
footer_para.text = "页码:"
footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 添加列表
doc.add_heading('项目列表', level=2)
for item in ['项目一', '项目二', '项目三']:
doc.add_paragraph(item, style='List Bullet')
# 添加有序列表
doc.add_heading('步骤列表', level=2)
for i, step in enumerate(['第一步', '第二步', '第三步'], 1):
doc.add_paragraph(step, style='List Number')
# 保存
doc.save('advanced.docx')
print('高级功能文档创建完成!')
6. 批量处理文档
from docx import Document
import os
def batch_replace_text(folder_path, old_text, new_text):
"""批量替换文件夹中所有DOCX文件的文本"""
for filename in os.listdir(folder_path):
if filename.endswith('.docx'):
filepath = os.path.join(folder_path, filename)
try:
doc = Document(filepath)
modified = False
# 替换段落中的文本
for para in doc.paragraphs:
if old_text in para.text:
for run in para.runs:
if old_text in run.text:
run.text = run.text.replace(old_text, new_text)
modified = True
# 替换表格中的文本
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
if old_text in cell.text:
cell.text = cell.text.replace(old_text, new_text)
modified = True
# 如果有修改,保存文档
if modified:
doc.save(filepath)
print(f'已修改: {filename}')
except Exception as e:
print(f'处理 {filename} 时出错: {e}')
# 使用示例
# batch_replace_text('./documents', '旧文本', '新文本')
def extract_all_text(folder_path, output_file):
"""提取文件夹中所有DOCX文件的文本"""
with open(output_file, 'w', encoding='utf-8') as f:
for filename in os.listdir(folder_path):
if filename.endswith('.docx'):
filepath = os.path.join(folder_path, filename)
try:
doc = Document(filepath)
f.write(f'=== {filename} ===\n')
for para in doc.paragraphs:
f.write(para.text + '\n')
f.write('\n')
print(f'已提取: {filename}')
except Exception as e:
print(f'提取 {filename} 时出错: {e}')
# 使用示例
# extract_all_text('./documents', 'output.txt')
print('批量处理函数已定义')
Go语言处理DOCX文件
使用unioffice库高效处理DOCX文件
高效
1. 安装unioffice库
# 使用go get安装 go get github.com/unidoc/unioffice/document # 或者使用go install go install github.com/unidoc/unioffice/cli/docx@latest
2. 创建新文档
package main
import (
"fmt"
"github.com/unidoc/unioffice/color"
"github.com/unidoc/unioffice/common"
"github.com/unidoc/unioffice/document"
"github.com/unidoc/unioffice/measurement"
"github.com/unidoc/unioffice/schema/soo/wml"
)
func main() {
// 创建新文档
doc := document.New()
// 添加标题
doc.AddParagraph().AddRun().AddText("欢迎使用unioffice").SetStyle("Heading1")
// 添加段落
para := doc.AddParagraph()
para.AddRun().AddText("这是一个普通的段落文本。")
// 添加带格式的文本
formattedPara := doc.AddParagraph()
run := formattedPara.AddRun()
run.AddText("这是")
run.Properties().SetBold(true)
run = formattedPara.AddRun()
run.AddText("加粗的")
run.Properties().SetItalic(true)
run = formattedPara.AddRun()
run.AddText("文本。")
run.Properties().SetColor(color.Red)
// 设置字体大小
run.Properties().SetSize(14)
// 添加表格
doc.AddParagraph().AddRun().AddText("示例表格").SetStyle("Heading2")
table := doc.AddTable()
table.Properties().SetWidth(common.Inch * 6)
row := table.AddRow()
row.AddCell().AddParagraph().AddRun().AddText("姓名")
row.AddCell().AddParagraph().AddRun().AddText("年龄")
row.AddCell().AddParagraph().AddRun().AddText("职业")
row = table.AddRow()
row.AddCell().AddParagraph().AddRun().AddText("张三")
row.AddCell().AddParagraph().AddRun().AddText("25")
row.AddCell().AddParagraph().AddRun().AddText("工程师")
row = table.AddRow()
row.AddCell().AddParagraph().AddRun().AddText("李四")
row.AddCell().AddParagraph().AddRun().AddText("30")
row.AddCell().AddParagraph().AddRun().AddText("设计师")
// 设置表格样式
table.SetStyle("Light Grid Accent 1")
// 添加图片
doc.AddParagraph().AddRun().AddText("添加图片").SetStyle("Heading2")
imgPara := doc.AddParagraph()
imgRun := imgPara.AddRun()
if err := imgRun.AddImage("image.png"); err != nil {
fmt.Printf("添加图片失败: %v\n", err)
}
// 保存文档
if err := doc.SaveToFile("example.docx"); err != nil {
fmt.Printf("保存文档失败: %v\n", err)
} else {
fmt.Println("文档创建成功!")
}
}
3. 读取文档内容
package main
import (
"fmt"
"github.com/unidoc/unioffice/document"
)
func main() {
// 打开现有文档
doc, err := document.Open("example.docx")
if err != nil {
fmt.Printf("打开文档失败: %v\n", err)
return
}
// 读取所有段落
fmt.Println("=== 所有段落 ===")
for _, para := range doc.Paragraphs() {
fmt.Println(para.Text())
}
// 读取所有表格
fmt.Println("\n=== 所有表格 ===")
for _, table := range doc.Tables() {
for i, row := range table.Rows() {
for j, cell := range row.Cells() {
fmt.Printf("表格[%d][%d]: %s\n", i, j, cell.Paragraphs()[0].Text())
}
}
}
// 读取特定样式的内容
fmt.Println("\n=== 所有标题 ===")
for _, para := range doc.Paragraphs() {
if para.Style() != nil {
styleName := para.Style().Name()
if styleName == "Heading1" || styleName == "Heading2" {
fmt.Printf("%s: %s\n", styleName, para.Text())
}
}
}
// 获取文档属性
fmt.Println("\n=== 文档属性 ===")
if appProps := doc.AppProperties(); appProps != nil {
fmt.Printf("标题: %s\n", appProps.Title())
fmt.Printf("主题: %s\n", appProps.Subject())
}
}
4. 修改现有文档
package main
import (
"fmt"
"github.com/unidoc/unioffice/color"
"github.com/unidoc/unioffice/document"
)
func main() {
// 打开现有文档
doc, err := document.Open("example.docx")
if err != nil {
fmt.Printf("打开文档失败: %v\n", err)
return
}
// 修改段落文本
for _, para := range doc.Paragraphs() {
text := para.Text()
if text == "这是一个普通的段落文本。" {
// 清除原有内容
para.Clear()
// 添加新文本
run := para.AddRun()
run.AddText("这是修改后的段落")
run.Properties().SetBold(true)
run.Properties().SetColor(color.RGB(0, 102, 204))
}
}
// 修改表格数据
for _, table := range doc.Tables() {
for _, row := range table.Rows() {
for _, cell := range row.Cells() {
if len(cell.Paragraphs()) > 0 {
text := cell.Paragraphs()[0].Text()
if text == "张三" {
cell.Paragraphs()[0].Clear()
cell.Paragraphs()[0].AddRun().AddText("王五")
}
}
}
}
}
// 添加新段落
newPara := doc.AddParagraph()
newPara.AddRun().AddText("这是新添加的段落")
// 保存修改
if err := doc.SaveToFile("modified.docx"); err != nil {
fmt.Printf("保存文档失败: %v\n", err)
} else {
fmt.Println("文档修改完成!")
}
}
5. 高级功能
package main
import (
"fmt"
"github.com/unidoc/unioffice/color"
"github.com/unidoc/unioffice/common"
"github.com/unidoc/unioffice/document"
"github.com/unidoc/unioffice/measurement"
"github.com/unidoc/unioffice/schema/soo/wml"
)
func main() {
// 创建文档
doc := document.New()
// 添加分页符
doc.AddParagraph().AddRun().AddBreak(wml.BreakTypePage)
// 设置页眉
section := doc.Sections()[0]
header := section.Header()
headerPara := header.AddParagraph()
headerPara.AddRun().AddText("这是页眉")
// 设置页脚
footer := section.Footer()
footerPara := footer.AddParagraph()
footerPara.AddRun().AddText("这是页脚")
// 添加列表
doc.AddParagraph().AddRun().AddText("项目列表").SetStyle("Heading2")
items := []string{"项目一", "项目二", "项目三"}
for _, item := range items {
para := doc.AddParagraph()
para.Properties().SetNumberingLevel(0)
para.Properties().SetNumberingID(1)
para.AddRun().AddText(item)
}
// 添加有序列表
doc.AddParagraph().AddRun().AddText("步骤列表").SetStyle("Heading2")
steps := []string{"第一步", "第二步", "第三步"}
for i, step := range steps {
para := doc.AddParagraph()
para.Properties().SetNumberingLevel(0)
para.Properties().SetNumberingID(2)
para.AddRun().AddText(step)
}
// 设置段落对齐
centerPara := doc.AddParagraph()
centerPara.Properties().SetAlignment(wml.JcAlignCenter)
centerPara.AddRun().AddText("居中对齐的文本")
// 设置段落缩进
indentPara := doc.AddParagraph()
indentPara.Properties().SetFirstLineIndent(common.Inch * 0.5)
indentPara.AddRun().AddText("首行缩进的文本")
// 设置行间距
spacingPara := doc.AddParagraph()
spacingPara.Properties().SetSpacing(wml.ST_DocGrid{Val: wml.ST_DocGridLines240})
spacingPara.AddRun().AddText("1.5倍行间距的文本")
// 保存
if err := doc.SaveToFile("advanced.docx"); err != nil {
fmt.Printf("保存文档失败: %v\n", err)
} else {
fmt.Println("高级功能文档创建完成!")
}
}
6. 并发处理文档
package main
import (
"fmt"
"os"
"path/filepath"
"sync"
"github.com/unidoc/unioffice/document"
)
// 并发处理文档
func processDocument(filename string, wg *sync.WaitGroup, results chan<- string) {
defer wg.Done()
filepath := filepath.Join("./documents", filename)
doc, err := document.Open(filepath)
if err != nil {
results <- fmt.Sprintf("处理 %s 失败: %v", filename, err)
return
}
// 处理文档内容
textCount := 0
for _, para := range doc.Paragraphs() {
textCount += len(para.Text())
}
results <- fmt.Sprintf("处理 %s 完成,文本长度: %d", filename, textCount)
}
func batchProcess(folderPath string) {
files, err := os.ReadDir(folderPath)
if err != nil {
fmt.Printf("读取文件夹失败: %v\n", err)
return
}
var wg sync.WaitGroup
results := make(chan string, len(files))
// 并发处理每个文档
for _, file := range files {
if !file.IsDir() && filepath.Ext(file.Name()) == ".docx" {
wg.Add(1)
go processDocument(file.Name(), &wg, results)
}
}
// 等待所有goroutine完成
go func() {
wg.Wait()
close(results)
}()
// 收集结果
for result := range results {
fmt.Println(result)
}
}
func main() {
fmt.Println("并发处理文档示例")
// batchProcess("./documents")
fmt.Println("并发处理函数已定义")
}
Python vs Go 对比
Python
优点
- ✓ 简单易学,语法清晰
- ✓ 库丰富,功能完善
- ✓ 开发速度快
- ✓ 社区活跃,文档齐全
缺点
- ✗ 性能相对较低
- ✗ 内存占用较高
- ✗ 并发模型有限
适用场景
- • 快速原型开发
- • 数据处理和分析
- • 自动化脚本
- • 小规模文档处理
Go
优点
- ✓ 性能优秀,编译型语言
- ✓ 内存占用低
- ✓ 原生支持并发
- ✓ 部署简单,单文件
缺点
- ✗ 学习曲线较陡
- ✗ 库相对较少
- ✗ 开发效率较低
适用场景
- • 高性能要求
- • 大规模文档处理
- • 并发批量处理
- • 服务端应用
💡 推荐建议
选择Python:如果您是初学者,需要快速开发,或者处理文档的数量不多,Python是更好的选择。python-docx库功能完善,文档丰富,学习成本低。
选择Go:如果您需要处理大量文档,对性能有要求,或者需要将文档处理功能集成到高性能服务中,Go是更好的选择。unioffice库性能优秀,支持并发处理。