Python操作Word和PowerPoint文件
操作Word文档
命令来安装python-docx
三方库。
pip install python-docx

from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
import matplotlib.pyplot as plt
from datetime import datetime
import io
def generate_sales_report():
# 创建文档对象
doc = Document()
# 设置文档默认字体(支持中文)
doc.styles['Normal'].font.name = '微软雅黑'
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
# ========== 1. 添加报告标题 ==========
title = doc.add_heading('2023年11月销售分析报告', level=0)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
title_run = title.runs[0]
title_run.font.size = Pt(22)
title_run.font.color.rgb = RGBColor(0, 0, 139) # 深蓝色
# 添加报告日期
current_date = datetime.now().strftime('%Y年%m月%d日')
date_para = doc.add_paragraph(f'生成日期:{current_date}')
date_para.alignment = WD_ALIGN_PARAGRAPH.RIGHT
date_para.runs[0].font.size = Pt(10)
date_para.runs[0].font.color.rgb = RGBColor(128, 128, 128) # 灰色
doc.add_paragraph() # 空行
# ========== 2. 添加基本信息 ==========
doc.add_heading('一、基本信息', level=1)
info_text = (
"本月销售报告涵盖2023年11月1日至11月30日的销售数据。"
"报告分析了平台整体销售情况、各品类表现、用户购买行为等关键指标,"
"并为下月运营策略提供数据支持。"
)
info_para = doc.add_paragraph(info_text)
info_para.runs[0].font.size = Pt(12)
# ========== 3. 添加销售数据表格 ==========
doc.add_heading('二、销售数据概览', level=1)
# 模拟销售数据
sales_data = [
['品类', '销售额(万元)', '订单数', '同比增幅', '毛利率'],
['电子产品', 1250, 8560, '12.5%', '22.3%'],
['家居用品', 890, 12450, '8.7%', '28.1%'],
['服装鞋帽', 760, 21500, '15.2%', '35.4%'],
['食品生鲜', 680, 18760, '23.8%', '18.9%'],
['其他', 320, 5600, '-2.1%', '15.6%']
]
# 创建表格
table = doc.add_table(rows=1, cols=len(sales_data[0]))
table.style = 'Light Shading Accent 1' # 使用内置表格样式
table.alignment = WD_TABLE_ALIGNMENT.CENTER
# 添加表头
hdr_cells = table.rows[0].cells
for i, header in enumerate(sales_data[0]):
hdr_cells[i].text = header
hdr_cells[i].paragraphs[0].runs[0].font.bold = True
hdr_cells[i].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
# 添加数据行
for row in sales_data[1:]:
row_cells = table.add_row().cells
for i, cell in enumerate(row):
row_cells[i].text = str(cell)
if i > 0: # 非第一列数据居中
row_cells[i].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
doc.add_paragraph() # 空行
# ========== 4. 添加销售趋势图 ==========
doc.add_heading('三、销售趋势分析', level=1)
# 生成一个简单的趋势图(实际应用中可以从数据库获取真实数据)
days = range(1, 31)
sales = [100 + x * 5 + (x % 7) * 20 for x in days] # 模拟每日销售额
plt.figure(figsize=(8, 4))
plt.plot(days, sales, marker='o', linestyle='-', color='#1f77b4')
plt.title('11月每日销售额趋势', fontproperties='SimHei')
plt.xlabel('日期', fontproperties='SimHei')
plt.ylabel('销售额(万元)', fontproperties='SimHei')
plt.grid(True)
# 将图表保存到内存中
img_stream = io.BytesIO()
plt.savefig(img_stream, format='png', dpi=300)
plt.close()
# 将图表添加到Word文档
img_stream.seek(0)
doc.add_picture(img_stream, width=Inches(6))
doc.add_paragraph('图1:11月每日销售额趋势图', style='Caption')
# ========== 5. 添加关键指标分析 ==========
doc.add_heading('四、关键指标分析', level=1)
analysis_points = [
("1. 总体表现", "本月总销售额达到3900万元,同比增长14.2%,环比增长8.7%。"),
("2. 品类亮点", "服装鞋帽品类表现突出,同比增长15.2%,主要得益于双十一促销活动。"),
("3. 用户行为", "平均客单价提升至320元,老客户复购率提升至45.6%。"),
("4. 促销效果", "双十一当天销售额达580万元,占全月销售额的14.9%。")
]
for point in analysis_points:
p = doc.add_paragraph()
p.add_run(point[0]).bold = True
p.add_run(" " + point[1])
# ========== 6. 添加结论与建议 ==========
doc.add_heading('五、结论与建议', level=1)
recommendations = [
"1. 继续保持服装鞋帽品类的营销投入,扩大竞争优势。",
"2. 针对食品生鲜品类的高增长,优化供应链管理。",
"3. 分析电子产品品类增长放缓原因,调整产品结构。",
"4. 策划12月年终促销活动,重点关注老客户唤醒。"
]
for rec in recommendations:
doc.add_paragraph(rec, style='List Bullet')
# ========== 7. 添加页脚 ==========
section = doc.sections[0]
footer = section.footer
footer_para = footer.paragraphs[0]
footer_para.text = "机密 - 仅限内部使用"
footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
footer_para.runs[0].font.size = Pt(9)
footer_para.runs[0].font.color.rgb = RGBColor(128, 128, 128)
# ========== 保存文档 ==========
report_name = f"销售分析报告_{current_date}.docx"
doc.save(report_name)
print(f"报告已生成: {report_name}")
if __name__ == "__main__":
generate_sales_report()

生成PowerPoint
安装名为python-pptx
的三方库,命令如下所示。
pip install python-pptx

from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.enum.shapes import MSO_SHAPE, MSO_CONNECTOR
from pptx.enum.text import MSO_ANCHOR
from datetime import datetime
import math
def create_ai_evolution_ppt():
# 创建演示文稿对象
prs = Presentation()
# ========== 1. 封面页 ==========
slide_layout = prs.slide_layouts[0] # 标题幻灯片布局
slide = prs.slides.add_slide(slide_layout)
title = slide.shapes.title
title.text = "人工智能演变历程"
title.text_frame.paragraphs[0].font.size = Pt(44)
title.text_frame.paragraphs[0].font.bold = True
title.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 32, 96) # 深蓝色
subtitle = slide.placeholders[1]
subtitle.text = "从理论萌芽到变革未来\n技术发展全景解析"
subtitle.text_frame.paragraphs[0].font.size = Pt(24)
subtitle.text_frame.paragraphs[0].font.color.rgb = RGBColor(128, 128, 128)
subtitle.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# 添加日期和作者
left = Inches(5.5)
top = Inches(6.5)
width = Inches(3)
height = Inches(0.5)
text_box = slide.shapes.add_textbox(left, top, width, height)
tf = text_box.text_frame
p = tf.add_paragraph()
p.text = f"生成日期: {datetime.now().strftime('%Y-%m-%d')}"
p.font.size = Pt(12)
p.font.color.rgb = RGBColor(150, 150, 150)
p.alignment = PP_ALIGN.RIGHT
# ========== 2. AI发展时间线 ==========
slide = prs.slides.add_slide(prs.slide_layouts[1]) # 标题和内容布局
title = slide.shapes.title
title.text = "AI发展时间线"
# 创建时间线图形
left = Inches(0.5)
top = Inches(1.5)
width = Inches(9)
height = Inches(1)
timeline = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height / 4)
timeline.fill.solid()
timeline.fill.fore_color.rgb = RGBColor(0, 112, 192)
# 添加时间点
milestones = [
(0.1, "1950s", "图灵测试\n达特茅斯会议"),
(0.35, "1980s", "专家系统\n机器学习兴起"),
(0.6, "1997", "深蓝击败\n国际象棋冠军"),
(0.75, "2011", "Siri发布\n语音助手时代"),
(0.9, "2023", "GPT-4\n多模态AI")
]
for pos, year, desc in milestones:
# 时间点标记
left_pos = left + width * pos - Inches(0.15)
marker = slide.shapes.add_shape(
MSO_SHAPE.OVAL,
left_pos,
top - Inches(0.15),
Inches(0.3),
Inches(0.3)
)
marker.fill.solid()
marker.fill.fore_color.rgb = RGBColor(237, 125, 49) # 橙色
marker.line.color.rgb = RGBColor(255, 255, 255)
# 年份文本
txBox = slide.shapes.add_textbox(
left_pos,
top - Inches(0.5),
Inches(0.8),
Inches(0.4))
tf = txBox.text_frame
p = tf.add_paragraph()
p.text = year
p.font.size = Pt(14)
p.font.bold = True
p.alignment = PP_ALIGN.CENTER
# 描述文本
txBox = slide.shapes.add_textbox(
left_pos - Inches(0.5),
top + Inches(0.3),
Inches(1.5),
Inches(0.8))
tf = txBox.text_frame
p = tf.add_paragraph()
p.text = desc
p.font.size = Pt(12)
p.alignment = PP_ALIGN.CENTER
# ========== 3. 关键里程碑 ==========
slide = prs.slides.add_slide(prs.slide_layouts[1])
title = slide.shapes.title
title.text = "AI发展关键里程碑"
# 使用SmartArt替代图形(实际使用中可以用真实SmartArt)
milestones = [
("1956", "达特茅斯会议", "AI概念正式提出"),
("1997", "深蓝胜利", "首次计算机击败国际象棋世界冠军"),
("2012", "AlexNet", "深度学习革命开始"),
("2016", "AlphaGo", "击败围棋冠军李世石"),
("2020", "GPT-3", "1750亿参数语言模型")
]
left = Inches(0.5)
top = Inches(1.5)
width = Inches(3)
height = Inches(0.8)
for i, (year, event, desc) in enumerate(milestones):
# 添加年份框
year_box = slide.shapes.add_shape(
MSO_SHAPE.ROUNDED_RECTANGLE,
left,
top + i * Inches(1.1),
width / 3,
height / 2
)
year_box.fill.solid()
year_box.fill.fore_color.rgb = RGBColor(54, 96, 146) # 深蓝色
year_box.line.color.rgb = RGBColor(255, 255, 255)
tf = year_box.text_frame
p = tf.add_paragraph()
p.text = year
p.font.size = Pt(14)
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
# 添加事件框
event_box = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE,
left + width / 3 + Inches(0.2),
top + i * Inches(1.1),
width * 0.7,
height
)
event_box.fill.solid()
event_box.fill.fore_color.rgb = RGBColor(218, 238, 243) # 浅蓝色
tf = event_box.text_frame
p = tf.add_paragraph()
p.text = event
p.font.size = Pt(16)
p.font.bold = True
p = tf.add_paragraph()
p.text = desc
p.font.size = Pt(12)
# ========== 4. 技术突破图解 ==========
slide = prs.slides.add_slide(prs.slide_layouts[1])
title = slide.shapes.title
title.text = "AI核心技术突破"
# 添加技术演进图(简化版)
technologies = [
("规则系统", "1950s-1980s", "专家系统", RGBColor(166, 166, 166)),
("机器学习", "1980s-2010s", "统计学习", RGBColor(155, 187, 89)),
("深度学习", "2010s-现在", "神经网络", RGBColor(79, 129, 189)),
("大模型", "2020s-现在", "Transformer", RGBColor(247, 150, 70))
]
left = Inches(0.5)
top = Inches(2)
width = Inches(2.5)
height = Inches(2)
for i, (tech, period, desc, color) in enumerate(technologies):
# 添加技术框
tech_box = slide.shapes.add_shape(
MSO_SHAPE.ROUNDED_RECTANGLE,
left + i * Inches(2.5),
top,
width,
height
)
tech_box.fill.solid()
tech_box.fill.fore_color.rgb = color
tech_box.line.color.rgb = RGBColor(255, 255, 255)
tf = tech_box.text_frame
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
p = tf.add_paragraph()
p.text = tech
p.font.size = Pt(18)
p.font.bold = True
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
p = tf.add_paragraph()
p.text = period
p.font.size = Pt(14)
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
p = tf.add_paragraph()
p.text = desc
p.font.size = Pt(12)
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
# 添加箭头连接
for i in range(len(technologies) - 1):
arrow = slide.shapes.add_shape(
MSO_SHAPE.RIGHT_ARROW,
left + (i + 1) * Inches(2.5) - Inches(0.3),
top + height / 2 - Inches(0.1),
Inches(0.6),
Inches(0.2)
)
arrow.fill.solid()
arrow.fill.fore_color.rgb = RGBColor(89, 89, 89)
# ========== 5. 当前应用领域 ==========
slide = prs.slides.add_slide(prs.slide_layouts[1])
title = slide.shapes.title
title.text = "AI当前主要应用领域"
applications = [
("医疗健康", "影像诊断、药物研发", "🏥"),
("金融服务", "风控、量化交易", "💳"),
("智能制造", "质检、预测性维护", "🏭"),
("自动驾驶", "环境感知、路径规划", "🚗"),
("内容创作", "AIGC、艺术创作", "🎨")
]
left = Inches(0.5)
top = Inches(1.8)
width = Inches(4)
height = Inches(1.2)
for i, (field, desc, emoji) in enumerate(applications):
row = i % 2
col = i // 2
# 添加应用框
app_box = slide.shapes.add_shape(
MSO_SHAPE.ROUNDED_RECTANGLE,
left + col * Inches(4.5),
top + row * Inches(1.5),
width,
height
)
app_box.fill.solid()
app_box.fill.fore_color.rgb = RGBColor(240, 240, 240)
tf = app_box.text_frame
p = tf.add_paragraph()
p.text = f"{emoji} {field}"
p.font.size = Pt(18)
p.font.bold = True
p = tf.add_paragraph()
p.text = desc
p.font.size = Pt(14)
# ========== 6. 未来趋势预测 ==========
slide = prs.slides.add_slide(prs.slide_layouts[1])
title = slide.shapes.title
title.text = "AI未来发展趋势"
trends = [
("AGI研究", "通用人工智能探索"),
("AI伦理", "可解释性、公平性、隐私保护"),
("边缘AI", "设备端智能计算"),
("AI+科学", "科学研究新范式"),
("人机协作", "增强人类能力而非替代")
]
left = Inches(0.5)
top = Inches(1.8)
radius = Inches(0.4)
# 添加中心主题
center = slide.shapes.add_shape(
MSO_SHAPE.OVAL,
left + Inches(3.5) - radius,
top + Inches(1.5) - radius,
radius * 2,
radius * 2
)
center.fill.solid()
center.fill.fore_color.rgb = RGBColor(0, 112, 192)
tf = center.text_frame
p = tf.add_paragraph()
p.text = "AI未来"
p.font.size = Pt(16)
p.font.bold = True
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
# 添加周围趋势节点
angles = [0, 72, 144, 216, 288] # 五等分圆
distance = Inches(2.5)
for i, (trend, desc) in enumerate(trends):
angle = angles[i] * 3.14159 / 180
x = left + Inches(3.5) + distance * math.cos(angle) - radius
y = top + Inches(1.5) + distance * math.sin(angle) - radius
node = slide.shapes.add_shape(
MSO_SHAPE.OVAL,
x,
y,
radius * 2,
radius * 2
)
node.fill.solid()
node.fill.fore_color.rgb = RGBColor(237, 125, 49)
tf = node.text_frame
p = tf.add_paragraph()
p.text = trend
p.font.size = Pt(14)
p.font.bold = True
p.font.color.rgb = RGBColor(255, 255, 255)
p.alignment = PP_ALIGN.CENTER
# 添加连接线 - 修复这里
line = slide.shapes.add_connector(
MSO_CONNECTOR.STRAIGHT, # 修改为正确的连接线类型
left + Inches(3.5),
top + Inches(1.5),
x + radius,
y + radius
)
line.line.width = Pt(1.5)
line.line.color.rgb = RGBColor(150, 150, 150)
# 添加描述文本框
desc_box = slide.shapes.add_textbox(
x - Inches(0.5) if angle < 3.14159 else x + Inches(0.5),
y + radius * 2,
Inches(1.5),
Inches(0.8)
)
tf = desc_box.text_frame
p = tf.add_paragraph()
p.text = desc
p.font.size = Pt(12)
p.alignment = PP_ALIGN.CENTER
# ========== 7. 结束页 ==========
slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空白布局
left = Inches(1)
top = Inches(2)
width = Inches(8)
height = Inches(2)
# 添加结束语
text_box = slide.shapes.add_textbox(left, top, width, height)
tf = text_box.text_frame
p = tf.add_paragraph()
p.text = "人工智能的演变仍在继续..."
p.font.size = Pt(36)
p.font.bold = True
p.font.color.rgb = RGBColor(0, 32, 96)
p.alignment = PP_ALIGN.CENTER
p = tf.add_paragraph()
p.text = "准备好迎接AI驱动的未来了吗?"
p.font.size = Pt(24)
p.font.color.rgb = RGBColor(128, 128, 128)
p.alignment = PP_ALIGN.CENTER
# 添加公司/作者信息
left = Inches(3)
top = Inches(6)
width = Inches(4)
height = Inches(0.5)
text_box = slide.shapes.add_textbox(left, top, width, height)
tf = text_box.text_frame
p = tf.add_paragraph()
p.text = "© 2023 AI趋势分析团队"
p.font.size = Pt(12)
p.font.color.rgb = RGBColor(150, 150, 150)
p.alignment = PP_ALIGN.CENTER
# ========== 保存PPT ==========
ppt_name = f"AI演变历程_{datetime.now().strftime('%Y%m%d')}.pptx"
prs.save(ppt_name)
print(f"PPT已生成: {ppt_name}")
if __name__ == "__main__":
create_ai_evolution_ppt()
Python操作PDF文件
PDF 是 Portable Document Format 的缩写,这类文件通常使用.pdf
作为其扩展名。
从PDF中提取文本
在 Python 中,可以使用名为PyPDF2
的三方库来读取 PDF 文件
pip install PyPDF2
pip install reportlab
PyPDF2
没有办法从 PDF 文档中提取图像、图表或其他媒体,但它可以提取文本,并将其返回为 Python 字符串。创建 PDF 文档需要三方库reportlab
的支持


import os
from PyPDF2 import PdfReader, PdfWriter, PdfMerger
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from io import BytesIO
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
def create_holiday_announcement(output_path):
"""创建公司放假公告PDF(使用 ReportLab 内置中文字体)"""
# 注册 ReportLab 内置的亚洲字体
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light")) # 宋体
# 创建PDF
packet = BytesIO()
c = canvas.Canvas(packet, pagesize=letter)
# 设置中文字体
c.setFont("STSong-Light", 12) # 使用注册的中文字体
# 添加中文内容
text = c.beginText(100, 650)
text.textLines("""
尊敬的全体员工:
根据国家法定节假日安排,结合公司实际情况,现将2023年春节放假安排通知如下:
1. 放假时间:2023年1月21日(星期六)至2023年1月27日(星期五),共7天。
2. 1月28日(星期六)、1月29日(星期日)正常上班。
3. 请各部门提前安排好工作,做好节前安全检查。
4. 放假期间,请保持通讯畅通,如有紧急情况及时联系相关负责人。
祝大家春节愉快,阖家幸福!
人事行政部
2023年1月10日
""")
c.drawText(text)
c.save()
packet.seek(0)
with open(output_path, "wb") as f:
f.write(packet.getvalue())
print(f"已创建放假公告PDF文件: {output_path}")
def encrypt_pdf(input_path, output_path, password):
"""加密PDF文件"""
reader = PdfReader(input_path)
writer = PdfWriter()
# 添加所有页面到writer
for page in reader.pages:
writer.add_page(page)
# 加密PDF
writer.encrypt(password)
# 写入输出文件
with open(output_path, "wb") as f:
writer.write(f)
print(f"已加密PDF文件并保存为: {output_path} (密码: {password})")
def add_watermark(input_path, output_path, watermark_text):
"""为PDF添加文字水印"""
reader = PdfReader(input_path)
writer = PdfWriter()
# 注册 ReportLab 内置的亚洲字体
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light")) # 宋体
# 创建水印PDF
watermark_packet = BytesIO()
c = canvas.Canvas(watermark_packet, pagesize=letter)
c.setFont("STSong-Light", 50)
c.setFillColorRGB(0.8, 0.8, 0.8) # 浅灰色
c.rotate(45) # 旋转45度
c.drawString(150, 50, watermark_text) # 水印文字
c.save()
watermark_packet.seek(0)
watermark_reader = PdfReader(watermark_packet)
watermark_page = watermark_reader.pages[0]
# 为每一页添加水印
for page in reader.pages:
page.merge_page(watermark_page)
writer.add_page(page)
# 写入输出文件
with open(output_path, "wb") as f:
writer.write(f)
print(f"已添加水印并保存为: {output_path}")
def batch_add_watermark(input_dir, output_dir, watermark_text):
"""批量添加水印"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(input_dir):
if filename.endswith(".pdf"):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, f"watermarked_{filename}")
add_watermark(input_path, output_path, watermark_text)
print(f"已完成批量添加水印,输出目录: {output_dir}")
def merge_pdfs(input_paths, output_path):
"""合并多个PDF文件"""
merger = PdfMerger()
for path in input_paths:
merger.append(path)
merger.write(output_path)
merger.close()
print(f"已合并PDF文件并保存为: {output_path}")
def read_pdf_metadata(input_path):
"""读取PDF元数据"""
reader = PdfReader(input_path)
metadata = reader.metadata
print("\nPDF文件元数据:")
print(f"标题: {metadata.get('/Title', '无')}")
print(f"作者: {metadata.get('/Author', '无')}")
print(f"创建者: {metadata.get('/Creator', '无')}")
print(f"创建日期: {metadata.get('/CreationDate', '无')}")
print(f"修改日期: {metadata.get('/ModDate', '无')}")
print(f"页数: {len(reader.pages)}")
def main():
# 1. 创建放假公告PDF
announcement_file = "holiday_announcement.pdf"
create_holiday_announcement(announcement_file)
# 2. 读取PDF元数据
read_pdf_metadata(announcement_file)
#
# # 3. 加密PDF
encrypted_file = "encrypted_holiday_announcement.pdf"
encrypt_pdf(announcement_file, encrypted_file, "company123")
#
# # 4. 添加水印
watermarked_file = "watermarked_holiday_announcement.pdf"
add_watermark(announcement_file, watermarked_file, "公司机密")
#
# # 5. 批量添加水印(示例)
# # 首先创建一些示例PDF
sample_files = ["sample1.pdf", "sample2.pdf"]
for i, filename in enumerate(sample_files, 1):
create_holiday_announcement(filename)
#
# # 创建输入输出目录
if not os.path.exists("input_pdfs"):
os.makedirs("input_pdfs")
if not os.path.exists("output_pdfs"):
os.makedirs("output_pdfs")
#
# # 移动示例PDF到输入目录
for filename in sample_files:
os.rename(filename, os.path.join("input_pdfs", filename))
#
# # 批量添加水印
batch_add_watermark("input_pdfs", "output_pdfs", "内部文件")
#
# # 6. 合并PDF
merged_file = "merged_documents.pdf"
merge_pdfs([announcement_file, watermarked_file], merged_file)
print("\n所有操作已完成!")
if __name__ == "__main__":
main()

Python处理图像
入门知识
- 颜色。如果你有使用颜料画画的经历,那么一定知道混合红、黄、蓝三种颜料可以得到其他的颜色,事实上这三种颜色就是美术中的三原色,它们是不能再分解的基本颜色。在计算机中,我们可以将红、绿、蓝三种色光以不同的比例叠加来组合成其他的颜色,因此这三种颜色就是色光三原色。在计算机系统中,我们通常会将一个颜色表示为一个 RGB 值或 RGBA 值(其中的 A 表示 Alpha 通道,它决定了透过这个图像的像素,也就是透明度)。
|----------|-----------------|-----------|---------------|
| 名称 | RGB值 | 名称 | RGB值 |
| White(白) | (255, 255, 255) | Red(红) | (255, 0, 0) |
| Green(绿) | (0, 255, 0) | Blue(蓝) | (0, 0, 255) |
| Gray(灰) | (128, 128, 128) | Yellow(黄) | (255, 255, 0) |
| Black(黑) | (0, 0, 0) | Purple(紫) | (128, 0, 128) |
- 像素。对于一个由数字序列表示的图像来说,最小的单位就是图像上单一颜色的小方格,这些小方块都有一个明确的位置和被分配的色彩数值,而这些一小方格的颜色和位置决定了该图像最终呈现出来的样子,它们是不可分割的单位,我们通常称之为像素(pixel)。每一个图像都包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小,大家如果爱好拍照或者自拍,对像素这个词就不会陌生。
用Pillow处理图像
Pillow 是由从著名的 Python 图像处理库 PIL 发展出来的一个分支,通过 Pillow 可以实现图像压缩和图像处理等各种操作。可以使用下面的命令来安装 Pillow。
pip install pillow
from PIL import Image
# 读取图像获得Image对象
image = Image.open('a.jpeg')
# 通过Image对象的format属性获得图像的格式
print(image.format) # JPEG
# 通过Image对象的size属性获得图像的尺寸
print(image.size) # (500, 750)
# 通过Image对象的mode属性获取图像的模式
print(image.mode) # RGB
# 通过Image对象的show方法显示图像
# image.show()
# 剪裁图像
# 通过Image对象的crop方法指定剪裁区域剪裁图像
# image.crop((80, 20, 310, 360)).show()
# 生成缩略图
# 通过Image对象的thumbnail方法生成指定尺寸的缩略图
image.thumbnail((128, 128))
image.show()
# 旋转和翻转
image = Image.open('a.jpeg')
# 使用Image对象的rotate方法实现图像的旋转
image.rotate(45).show()
# 使用Image对象的transpose方法实现图像翻转
# Image.FLIP_LEFT_RIGHT - 水平翻转
# Image.FLIP_TOP_BOTTOM - 垂直翻转
image.transpose(Image.FLIP_TOP_BOTTOM).show()
# 操作像素
for x in range(80, 310):
for y in range(20, 360):
# 通过Image对象的putpixel方法修改图像指定像素点
image.putpixel((x, y), (128, 128, 128))
image.show()
# 滤镜效果
from PIL import ImageFilter
# 使用Image对象的filter方法对图像进行滤镜处理
# ImageFilter模块包含了诸多预设的滤镜也可以自定义滤镜
image.filter(ImageFilter.CONTOUR).show()
Pillow绘图
Pillow 中有一个名为ImageDraw
的模块,该模块的Draw
函数会返回一个ImageDraw
对象,通过ImageDraw
对象的arc
、line
、rectangle
、ellipse
、polygon
等方法,可以在图像上绘制出圆弧、线条、矩形、椭圆、多边形等形状,也可以通过该对象的text
方法在图像上添加文字。
from PIL import Image, ImageDraw, ImageFont
# 创建一个新的空白图像 (800x600 像素,白色背景)
width, height = 800, 600
image = Image.new('RGB', (width, height), 'white')
# 创建一个可以在图像上绘制的 Draw 对象
draw = ImageDraw.Draw(image)
# 1. 绘制矩形 (红色边框,不填充)
draw.rectangle([50, 50, 250, 200], outline='red', width=3)
# 2. 绘制填充矩形 (蓝色填充)
draw.rectangle([300, 50, 500, 200], fill='blue')
# 3. 绘制椭圆 (绿色边框,黄色填充)
draw.ellipse([50, 250, 250, 400], outline='green', fill='yellow', width=2)
# 4. 绘制线条 (紫色,5像素宽)
draw.line([300, 250, 500, 400], fill='purple', width=5)
# 5. 绘制多边形 (橙色边框,浅蓝色填充)
points = [(550, 50), (700, 150), (650, 300), (500, 250)]
draw.polygon(points, outline='orange', fill='lightblue', width=2)
# 6. 绘制圆弧 (红色,从30度到270度)
draw.arc([50, 450, 250, 550], start=30, end=270, fill='red', width=3)
# 7. 添加文字 (需要指定字体)
try:
# 尝试加载系统字体
font = ImageFont.truetype("arial.ttf", 24)
except:
# 如果找不到字体,使用默认字体
font = ImageFont.load_default()
draw.text((300, 450), "Hello, Pillow!", fill='black', font=font)
# 8. 添加大号彩色文字 (使用不同颜色)
large_font = ImageFont.truetype("arial.ttf", 40) if font != ImageFont.load_default() else ImageFont.load_default()
draw.text((300, 500), "ImageDraw Demo", fill=(255, 0, 128), font=large_font)
# 保存图像
image.save('draw_demo.png')
print("图像已保存为 draw_demo.png")
# 显示图像
image.show()
