python对word、excel和ppt操作
from docx import Document
# -*- coding: utf-8 -*-
import os
from docx import Document
import win32com.client
import datetime
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
i = datetime.datetime.now()
date = ("%s年%02d月%02d日" % (i.year, i.month, i.day))
time = ("%02d时%02d分%02d秒" % (i.hour, i.minute, i.second)) # 小时前有个空格为了send_email查找前两个字符转int型方便
Docx = Document()
Docx.add_heading("这是一个一级标题", level=1)
Docx.add_paragraph("更新于"+time, "Title").alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
A = Docx.add_paragraph("My name is aaa")
A.add_run("我学习的很快乐,啊哈哈哈哈哈,非常好 Good!!!")
Docx.add_heading("这是一个二级标题", level=2)
A = Docx.add_paragraph("这个是二级标题的内容呀")
B = A.add_run("二级标题里面的正文 继续添加!!!!!!!")
B.font.bold = True # 同时我要对这些正文进行加粗~~~~
B.font.size = (20)
Docx.add_heading("我爱学习Python以下就是python的logo呀", level=3)
# Docx.add_picture("1.png")
Docx.add_table(rows=5, cols=5)
Docx.save("D:\\Python.docx")
win32com 在word实现
读取图片处理
import win32com.client
def set_image_format(doc_path):
"""
设置Word文档中第一张图片的格式,包括大小、文字环绕和距正文的距离。
Parameters:
- doc_path (str): Word文档的文件路径。
Returns:
无
"""
# 打开Word应用
word = win32com.client.gencache.EnsureDispatch('kwps.Application')
word.Visible = True
# 打开文档
doc = word.Documents.Open(doc_path)
# 获取文档中的所有内联形状(包括图片)
inline_shapes = doc.InlineShapes
# 获取第一个内联形状
if inline_shapes.Count >= 1:
first_image = inline_shapes(1)
# 将内联形状转换为形状对象
shape = first_image.ConvertToShape()
# 设置图片大小
shape.LockAspectRatio = 0 # 允许调整宽度和高度独立
shape.Width = word.CentimetersToPoints(14.65) # 设置宽度
shape.Height = word.CentimetersToPoints(5.69) # 设置高度
# 设置文字环绕
shape.WrapFormat.Type = win32com.client.constants.wdWrapSquare # 四周型
shape.WrapFormat.Side = win32com.client.constants.wdWrapBoth # 环绕文字两边
# 设置距正文的距离
shape.WrapFormat.DistanceTop = 0 # 上:0厘米
shape.WrapFormat.DistanceBottom = 0 # 下:0厘米
shape.WrapFormat.DistanceLeft = word.CentimetersToPoints(0.32) # 左:0.32厘米
shape.WrapFormat.DistanceRight = word.CentimetersToPoints(0.32) # 右:0.32厘米
# 保存并关闭文档
doc.Save()
doc.Close()
读取图表处理
import win32com.client
def set_chart_format(doc_path):
"""
设置Word文档中第一个图表的格式,包括大小、文字环绕和距正文的距离。
Parameters:
- doc_path (str): Word文档的文件路径。
Returns:
无
"""
# 打开Word应用
word = win32com.client.gencache.EnsureDispatch('kwps.Application')
word.Visible = True
# 打开文档
doc = word.Documents.Open(doc_path)
# 获取文档中的所有形状
shapes = doc.Shapes
# 获取第一个图表
first_chart = shapes(1)
if first_chart:
# 设置图表大小
first_chart.Width = word.CentimetersToPoints(14.65)
first_chart.Height = word.CentimetersToPoints(5.69)
# 设置文字环绕
first_chart.WrapFormat.Type = win32com.client.constants.wdWrapSquare # 四周型
first_chart.WrapFormat.Side = win32com.client.constants.wdWrapBoth # 环绕文字两边
# 设置距正文的距离
first_chart.WrapFormat.DistanceTop = 0 # 上:0厘米
first_chart.WrapFormat.DistanceBottom = 0 # 下:0厘米
first_chart.WrapFormat.DistanceLeft = word.CentimetersToPoints(0.32) # 左:0.32厘米
first_chart.WrapFormat.DistanceRight = word.CentimetersToPoints(0.32) # 右:0.32厘米
# 设置位置为页边距
first_chart.RelativeHorizontalPosition = 1 # 1代表页边距
first_chart.RelativeVerticalPosition = 1 # 1代表页边距
# 保存并关闭文档
doc.Save()
doc.Close()
读取表格处理,复制、设置格式
import win32com.client
def copy_table_data(source_doc_path, target_doc_path, table=1):
"""
复制源Word文档中的表格数据到目标文档中,同时设置格式。
Parameters:
- source_doc_path (str): 源Word文档的文件路径。
- target_doc_path (str): 目标Word文档的文件路径。
- table (int): 要复制的表格的索引,默认为1。
Returns:
无
"""
# 打开Word应用
word = win32com.client.Dispatch('KWPS.Application')
# 打开源文档
source_doc = word.Documents.Open(source_doc_path)
source_table = source_doc.Tables.Item(table) # 获取第几个表格
# 打开目标文档
target_doc = word.Documents.Open(target_doc_path)
target_table = target_doc.Tables.Item(table) # 获取第几个表格
# 复制源表格的数据到目标表格,并设置格式
for row in range(1, source_table.Rows.Count + 1):
for col in range(1, source_table.Columns.Count + 1):
try:
text = source_table.Cell(row, col).Range.Text.strip().replace('\n', '').replace('\r', '').replace('\x07', '')
if text:
target_table.Cell(row, col).Range.Text = text
# 设置单元格格式
cell_range = target_table.Cell(row, col).Range
cell_range.Font.Name = 'Times New Roman' # 字体选择:Times New Roman
cell_range.Font.Size = 10.5 # 字号:五号
cell_range.Font.NameFarEast = '仿宋_GB2312' # 汉字字体:仿宋_GB2312
# 设置特定行的格式
if table == 1:
if col in [5, 9, 13, 17, 18, 19]: # 列索引[5, 9, 13, 17, 18, 19]
cell_range.Font.Bold = True
elif '合计' in text or '月均' in text:
cell_range.Font.Bold = True
else:
cell_range.Font.Bold = False
elif table == 2:
if 'XXXX有限公司' in text:
for col in range(1, target_table.Columns.Count + 1):
target_table.Cell(row, col).Range.Font.Bold = True
except Exception as e:
pass
# 关闭文档和Word应用
source_doc.Close()
target_doc.Save()
target_doc.Close()
# 请注意,上述代码中的路径和索引可能需要根据实际情况进行调整。
#!/usr/bin/env python3
# coding: utf-8
import xlrd
import xlwt
# 打开excel文件,创建一个workbook对象,book对象也就是fruits.xlsx文件,表含有sheet名
rbook = xlrd.open_workbook("C:\\Users\\yys53\\Desktop\\333(1).xlsx")
# sheets方法返回对象列表,[<xlrd.sheet.Sheet object at 0x103f147f0>]
rbook.sheets()
# xls默认有3个工作簿,Sheet1,Sheet2,Sheet3
rsheet = rbook.sheet_by_index(0) # 取第一个工作簿
import re
# 循环工作簿的所有行
i = 0
workbook = xlwt.Workbook(encoding='gbk')
sheet = workbook.add_sheet("Miss")
for row in rsheet.get_rows():
i += 1
if i <=14:
a = re.compile("(.*?)(\\d+).*?(\d+.\d{15})", re.S).findall(row[0].value)
if a:
print(a[0])
sheet.write(i, 0, a[0][0].strip())
sheet.write(i, 1, a[0][1].strip())
sheet.write(i, 2, a[0][2].strip())
style = xlwt.easyxf('align: wrap on')
sheet.col(0).width = 256 * 20
else:
print(row[0].value)
if i > 14:
# print(row[0].value)
a = re.compile("KEGG_PATHWAY hsa\\d+:(.*?)(\\d+).*?(\d+.\d{15}).*?", re.S).findall(row[0].value)
if a:
print(a[0])
sheet.write(i, 0, a[0][0].strip())
sheet.write(i, 1, a[0][1].strip())
sheet.write(i, 2, a[0][2].strip())
sheet.col(0).width = 256 * 20
workbook.save('text.xls')
win32com.client.Dispatch
和 win32.gencache.EnsureDispatch
都是用于创建 Python 中的 COM 对象实例的方法,用于与外部的 COM 组件(例如 Microsoft Office 应用程序、Windows 脚本宿主等)进行交互。下面是它们之间的主要区别:
win32com.client.Dispatch
:- 这是
pywin32
包中的标准方法,用于动态地创建 COM 对象实例。 - 在每次调用
Dispatch
方法时,都会在运行时检查注册表以查找适当的 COM 对象,因此会稍微耗费一些时间。 - 适用于不确定对象类型或需要在运行时动态创建 COM 对象的情况。
- 这是
示例:
import win32com.client
excel = win32com.client.Dispatch("Excel.Application")
word = win32com.client.Dispatch("Word.Application")
win32.gencache.EnsureDispatch
:- 这是
pywin32
包中的另一种方法,用于创建 COM 对象实例。不同之处在于,它会在第一次调用时自动生成一个缓存的 Python 类,以加快后续调用。 - 第一次调用时,会生成 COM 对象的缓存 Python 类并存储在磁盘上,之后的调用将直接使用这个缓存的类,避免了运行时的注册表查找,因此速度更快。
- 适用于频繁地使用相同类型的 COM 对象,因为第一次创建时可能会有稍微的延迟。
- 这是
示例:
import win32.gencache
excel = win32.gencache.EnsureDispatch("Excel.Application")
word = win32.gencache.EnsureDispatch("Word.Application")
总结:如果您在代码中频繁地使用相同类型的 COM 对象,EnsureDispatch
可能会更有效,因为它在第一次创建后会自动生成缓存。如果您需要动态地创建不同类型的 COM 对象,或者对速度要求不是很高,可以使用 Dispatch
方法。
win32.gencache.EnsureDispatch
在性能方面通常会更快,因为它在第一次调用时会生成缓存的 Python 类,之后的调用会直接使用这个缓存的类,避免了运行时的注册表查找。这样可以减少对注册表的访问并加速 COM 对象的创建。
另一方面,win32com.client.Dispatch
是在每次调用时都会在运行时检查注册表来查找适当的 COM 对象,因此可能会稍微耗费一些时间。
总的来说,如果您在代码中频繁地使用相同类型的 COM 对象,win32.gencache.EnsureDispatch
可能会更有效,因为它会在第一次创建后生成缓存,并且后续的调用会受益于这个缓存。如果您需要动态地创建不同类型的 COM 对象,或者对速度要求不是很高,win32com.client.Dispatch
也是一个合适的选择。最终的选择取决于您的使用场景和性能需求。
需要安装pypiwin32
pip install pypiwin32
import win32com.client as win32
from win32com.client import constants
xls_app = win32.Dispatch('ket.Application')
file_name = r"C:\Users\yys53\PycharmProjects\untitled1\data.xlsx"
# xls_app = xls_app.Workbooks.Open(file_name)
# wb = xls_app.Workbooks.Add()
wb = xls_app.Workbooks.Open(file_name)
# wb = xls_app.Workbooks.Add() # excel不存在时候可以创建
ws = wb.Worksheets(1)
ws.Name = 'my_new_sheet'
xls_app.Visible = True
# wb.SaveAs('New_workbook.xlsx')
# 添加数据
ws.Range("A1").Value = "1"
ws.Range("A2").Value = "2"
ws.Range("A3").Value = "3"
ws.Range("A4").Value = "2"
ws.Range("A5").Value = "1"
ws.Range("A6").Value = "-1"
#ws.Range("A2", "C2").Value = "23" # 写入多列
# ws.column_dimensions["A"].hidden = True
# # 隐藏列
# ws.Columns("C").EntireColumn.Hidden = True
# # 隐藏行
# ws.Rows(3).EntireRow.Hidden = True
# 添加折线
# XlChartType 图表的类型
# left和top是按照像素来配置图表插入的位置
# def hidden_column(path, column, sheet_name=0):
# '''
# :param path: 文件路径
# :param column: 列名,如A,B,C,可以传入单个,可以是区间[B,E]
# :return:
# '''
# try:
# wb = load_workbook(path, data_only=True)
# if isinstance(sheet_name, str):
# ws = wb.get_sheet_by_name(sheet_name)
# else:
# ws = wb.worksheets[sheet_name]
# if isinstance(column, list):
# ws.column_dimensions.group(column[0], column[1], hidden=True)
# else:
# ws.column_dimensions[column].hidden = True
# wb.save(path)
# except Exception as e:
# print("打开文件失败:%s" % e)
new_shape=ws.Shapes.AddChart2(Left=20,Top=10)#
chart=new_shape.Chart
chart.ChartType = constants.xlXYScatterLines# 设置图表的类型
chart.SetSourceData(Source=ws.Range("A1:A6"))
# wb.ActiveChart.ChartTitle.Text = "图表"
# wb.ActiveChart.Delete('图表 1')
# my_new_sheet
# cha1 = ws.chart
# 设置标题ChartObjects(1)代表第一个图表
cha1 = wb.Worksheets("my_new_sheet").ChartObjects(1).Chart
cha1.HasTitle = True
wb.ActiveChart.ChartTitle.Text = "图表2"
wb.Save()
xls_app.Quit()
del xls_app
注意(我的wps用的ket版本的)
win32com.client.Dispatch("et.Application")#wps正式版
win32com.client.Dispatch("ket.Application")#wps抢先版
win32com.client.Dispatch("EXCEL.Application")#office EXCEL版
import time
import win32com.client as win32
xls_app = win32.Dispatch('ket.Application')
file_name = filepath
wb = xls_app.Workbooks.Open(file_name)
ws = wb.Worksheets('区域通报')
# ws.Name = '每日净增副本'
xls_app.Visible = True
# 写入控制防止没保存
# ws.Range("A1000").Value = ""
# # 隐藏列
# ws.Columns("C").EntireColumn.Hidden = True
for row in hide_col_list:
# 隐藏行
log.info("隐藏%s" % row)
ws.Rows(row).EntireRow.Hidden = True
for row in not_hide_col_list:
ws.Rows(row).EntireRow.Hidden = False
# # 隐藏列
# ws.Columns("C").EntireColumn.Hidden = True
log.info("file_name=%s" % file_name)
# xls_app.Save(r"F:\需要完成任务.xlsx")
time.sleep(2)
wb.Save()
wb.Close()
xls_app.Quit()
del xls_app
ws = wb.Worksheets('区域排名')
# ws.Name = '每日净增副本'
# sheet.Cells(row, col).Value
# 读取列
date = ws.Columns("F").Value
# 读取单元格
# ws.Cells(row, col).Value
# 读取行
one_list = ws.Rows("1").Value
读取一个sheet数据(所有内容)
sheet_data=ws.Worksheets(1).UsedRange.Value
使用numpy
定位数据中包含'银行'关键词的行列位置的示例
import numpy as np
# 假设 sheet_data 是你的 Excel 数据
data_array = np.array(sheet_data)
# 查找数组中包含'银行'的索引位置
indices = np.where(data_array == '银行')
# 由于索引从0开始,将结果加1以匹配 Excel 中的索引
row_index, col_index = indices
row_index = row_index[0] + 1
col_index = col_index[0] + 1
# 打印包含'银行'的行和列索引
print("包含 '银行' 的行索引:", row_index)
print("包含 '银行' 的列索引:", col_index)
import win32com.client
import os
xlApp = win32com.client.Dispatch('Excel.Application')
xlApp.Visible = False
xls = xlApp.Workbooks.Open(os.getcwd() + "\\test.xls")
sheet = xls.Worksheets(1)
info = sheet.UsedRange
nrows = info.Rows.Count
ncols = info.Columns.Count
xls.Close(SaveChanges=0)
ws.Range("A1:B1").Interior.ColorIndex=44 #刷单元格颜色
worksheet.Range(worksheet.Cells(row_number, 1), worksheet.Cells(row_number, worksheet.Columns.Count)).Interior.Color = (0x1C1CF5) # 设置一行颜色
ws.Range("A2").Font.ColorIndex=23 #刷字体颜色
ws.Range('A2:B2').NumberFormatLocal = "@" #设置单元格格式为文本
ws.Range("A1:B1").Font.Bold = True #加粗
ws.Range("C1:D1").Merge() #合并单元格,合并之后读写均需选中第一个单元格
ws.Range("A1:T1").Columns.AutoFit()
#自动调节边框宽度,有时调节出来不准确,需要手动再校正
ws.Range("A1").ColumnWidth = 40 # 手动设置宽度
.Font.ColorIndex方法
无色 = -4142,
自动 = -4105,
黑色 = 1,
白色 = 2
红色 = 3,
鲜绿 = 4,
蓝色 = 5,
黄色 = 6,
粉红 = 7,
青绿 = 8,
深红 = 9,
绿色 = 10,
深蓝 = 11,
深黄 = 12,
紫罗兰 = 13,
青色 = 14,
灰色25 = 15,
褐色 = 53,
橄榄 = 52,
深绿 = 51,
深青 = 49,
靛蓝 = 55,
灰色80 = 56,
橙色 = 46,
蓝灰 = 47,
灰色50 = 16,
浅橙色 = 45,
酸橙色 = 43,
海绿 = 50,
水绿色 = 42,
浅蓝 = 41,
灰色40 = 48,
金色 = 44,
天蓝 = 33,
梅红 = 54,
玫瑰红 = 38,
茶色 = 40,
浅黄 = 36,
浅绿 = 35,
浅青绿 = 34,
淡蓝 = 37,
淡紫 = 39,
2.6 新建一个空excel文件
from win32com.client import Dispatch
app = Dispatch ("Excel.Application")
wb = app.Workbooks.Add ()
wb.SaveAs('f:\myfile.xlsx')
方法1
使用 win32com
在 Excel 中对指定的单元格区域进行截图,并且保留彩色格式,可以使用 Excel 的 Range.CopyPicture
方法。该方法允许复制指定范围的图片,并可以将其粘贴到剪贴板,然后保存为图片文件。下面是一个示例代码,演示如何指定范围截图并保存为彩色图片:
import win32com.client as win32
from PIL import ImageGrab
# 打开 Excel 应用
excel = win32.Dispatch('Excel.Application')
# 打开已有的 Excel 文件
workbook = excel.Workbooks.Open(r"文件路径.xlsx")
# 选择工作表
sheet = workbook.Sheets(1)
# 指定截图范围(例如 A1 到 D10)
range_to_capture = sheet.Range("A1:D10")
# 复制指定范围为图片,指定 `Appearance` 为 `1`(xlScreen)保留彩色
range_to_capture.CopyPicture(Appearance=1, Format=2) # 1: 保持彩色, 2: 作为图片 (xlBitmap)
# 从剪贴板抓取图片
image = ImageGrab.grabclipboard()
# 检查是否成功抓取图片
if isinstance(image, ImageGrab.Image.Image):
# 保存图片到文件
image.save(r"C:\path\to\save\image.png", "PNG")
print("截图成功!图片已保存。")
else:
print("未能成功抓取图片,请检查范围或剪贴板。")
# 关闭工作簿
workbook.Close(SaveChanges=False)
# 退出 Excel 应用
excel.Quit()
代码解释:
range_to_capture.CopyPicture(Appearance=1, Format=2)
:CopyPicture
方法用于复制指定范围为图片。参数Appearance=1
表示保留彩色,Format=2
表示复制为图片格式。ImageGrab.grabclipboard()
:使用Pillow
库的ImageGrab
模块从剪贴板抓取图片。- 保存图片:抓取成功后,将图片保存为 PNG 格式。
关键点:
Appearance=1
:表示保留彩色(xlScreen
)。Format=2
:表示复制为位图格式图片(xlBitmap
)。ImageGrab.grabclipboard()
:从剪贴板抓取 Excel 复制的图片内容。
通过这种方式,你可以对 Excel 中的指定范围进行截图并保存为彩色图片。确保你已经安装了 Pillow
库来处理截图并保存图片(可以通过 pip install Pillow
来安装)。
方法2
from win32com.client import Dispatch, DispatchEx
import pythoncom
from PIL import ImageGrab, Image
import uuid
import time
# screen_area——类似格式"A1:J10"
def excel_catch_screen(filename, sheetname, screen_area, img_name='', pic_path=''):
""" 对excel的表格区域进行截图——用例:excel_catch_screen(ur"D:\Desktop\123.xlsx", "Sheet1", "A1:J10")"""
pythoncom.CoInitialize() # excel多线程相关
excel = DispatchEx('ket.Application') # 启动excel
excel.Visible = False # 可视化
excel.DisplayAlerts = False # 是否显示警告
wb = excel.Workbooks.Open(filename) # 打开excel
wb.Sheets(sheetname).select # 視圖切換到sheetname表
ws = wb.Sheets(sheetname) # 选择sheet
ws.Range(screen_area).CopyPicture() # 复制图片区域
ws.Paste() # 粘贴 ws.Paste(ws.Range('B1')) # 将图片移动到具体位置
time.sleep(1)
name = str(uuid.uuid4()) # 重命名唯一值
new_shape_name = name[:6]
excel.Selection.ShapeRange.Name = new_shape_name # 将刚刚选择的Shape重命名,避免与已有图片混淆
ws.Shapes(new_shape_name).Copy() # 选择图片
img = ImageGrab.grabclipboard() # 获取剪贴板的图片数据
if not img_name:
img_name = 'D:\\woai\\' + name + ".PNG"
print(img_name)
img.save(img_name) # 保存图片
wb.Close(SaveChanges=0) # 关闭工作薄,不保存
excel.Quit() # 退出excel
pythoncom.CoUninitialize()
if __name__ == '__main__':
pass
excel_catch_screen(r"D:\woai\资产报废模板.xlsx", "Sheet1", "A1:F5", img_name="D:\\woai\\ceshi.PNG")
主要使用到chartObject来获取chart对象。
import win32com.client as win32
from win32com.client import constants
file_name = r"D:\农行控制\data.xlsx"
xls_app = win32.gencache.EnsureDispatch('ket.Application')
# wb = xls_app.Workbooks.Add()
wb = xls_app.Workbooks.Open(file_name)
ws = wb.Worksheets(1)
ws.Name = 'my_new_sheet'
xls_app.Visible = True
chart = ws.ChartObjects('图表 1').Chart #获得chart对象
# chart = ws.ChartObjects(1).Chart # 方法2
chart.SetSourceData(ws.Range("A1:A5"))
下面这种复制表格的方法,往往会导致表格列宽度比较异常——超过页面宽度。
sheet=wb.Worksheets(1)#将变量sheet指向excel的第一张表
sheet.Range('A1:B5').Copy()# 复制表中A1到B5的范围,A1为左上角的单元格坐标,B5为右下角的坐标
parag=doc.doc.Paragraphs.Last#将变量parag指向word文档中最后一段的段尾
parag.Range.Paste()#粘贴刚才复制过的表格
保留源格式粘贴表格
为了解决上述的问题,可以先在excel中讲字体和表格列宽都调节好。然后粘贴的时候,选择保持原格式即可。
from win32com.client import constants
parag.Range.PasteAndFormat(constants.wdFormatOriginalFormatting)
以图片形式粘贴表格
还有一种比较省事的方法,就是把表格粘贴成图片。这样能保证表格能在页面宽度内显示完。缺点是无法编辑边表格内容。
sheet=wb.Worksheets(1)
sheet.Range('A1:B5').CopyPicture()# 只有这里和之前复制excel有差别
parag=doc.doc.Paragraphs.Last#
parag.Range.Paste()#以图片形式粘贴刚才复制过的表格
# 为某单元格写入公式,也可覆盖原有的公式
ws.Range("A1").Formula = '=COUNTIF(J15:J1424,"X")+COUNTIF(J15:J1424,"O")'
# 清除所有内容,包括格式,外边框,颜色等
ws.Range("A1:B5").Clear()
# 只清除单元格内容
ws.Range("A1:B5").ClearContents()
chart = ws.ChartObjects('图表 9').Chart #获得chart对象
chart.ChartTitle.Text = "1995 Rainfall Totals by Month"
x = chart.SeriesCollection('2023年加权利率').Points(100)
x.HasDataLabel = True
x.DataLabel.Text = "ewr"
module 'win32com.gen_py.45541000-5750-5300-4B49-4E47534F4655x0x3x0' has no attribute 'CLSIDToClassMap'
module 'win32com.gen_py.45541000-5750-5300-4B49-4E47534F4655x0x3x0' has no attribute 'CLSIDToClassMap'
raise e
File "C:\Users\user\AppData\Roaming\达观RPA开发平台\temp\run_file.py", line 52, in <module>
xls_app = win32.Dispatch('ket.Application')
File "D:\datagrand-rpa\rpa-studio\resources\main\server\win32\engine\lib\site-packages\win32com\client\__init__.py", line 96, in Dispatch
return __WrapDispatch(dispatch, userName, resultCLSID, typeinfo, clsctx=clsctx)
File "D:\datagrand-rpa\rpa-studio\resources\main\server\win32\engine\lib\site-packages\win32com\client\__init__.py", line 37, in __WrapDispatch
klass = gencache.GetClassForCLSID(resultCLSID)
File "D:\datagrand-rpa\rpa-studio\resources\main\server\win32\engine\lib\site-packages\win32com\client\gencache.py", line 183, in GetClassForCLSID
mod = GetModuleForCLSID(clsid)
File "D:\datagrand-rpa\rpa-studio\resources\main\server\win32\engine\lib\site-packages\win32com\client\gencache.py", line 226, in GetModuleForCLSID
可以尝试手动删除缓存文件。缓存文件通常位于用户目录的%USERPROFILE%\AppData\Local\Temp\gen_py文件夹中。你可以删除整个文件夹或者只删除与出现错误相关的缓存文件
使用python删除下面文件夹和文件
import os
import shutil
folder_path = os.path.expandvars("%USERPROFILE%\\AppData\\Local\\Temp\\gen_py")
# 首先删除文件夹下的所有文件
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print("删除失败")
1.多线程删除(33秒)
import win32com.client as win32
import os
import threading
import numpy as np
def check_empty_rows(data, start_row, end_row, result):
data_array = np.array(data)
columns = data_array.shape[1] if len(data_array) > 0 else 0
for row in range(end_row, start_row-1, -1):
if row-1 < len(data_array): # 检查索引是否超出范围
is_empty = True
for column in range(columns):
if data_array[row-1][column] is not None and str(data_array[row-1][column]).strip() != "":
is_empty = False
break
if is_empty:
result.append(row)
def delete_empty_rows(filepath):
excel = win32.gencache.EnsureDispatch('ket.Application')
excel.Visible = True
excel.DisplayAlerts = False
workbook = excel.Workbooks.Open(filepath)
worksheet = workbook.Worksheets(1)
data = worksheet.UsedRange.Value
total_rows = len(data)
threads = 4 # 设置您想要的线程数
rows_per_thread = total_rows // threads
result = []
thread_list = []
for i in range(threads):
start_row = i * rows_per_thread + 1
end_row = start_row + rows_per_thread
if i == threads - 1:
end_row = total_rows + 1
t = threading.Thread(target=check_empty_rows, args=(data, start_row, end_row, result))
thread_list.append(t)
t.start()
for t in thread_list:
t.join()
result.sort(reverse=True)
for row in result:
worksheet.Rows(row).Delete()
workbook.Save()
workbook.Close()
print("Empty rows deleted successfully.")
# 调用函数来执行操作
excel_filepath = r"D:\SAP报表导出\序时账\新需求\merged2023-06-01 - 副本.xlsx"
delete_empty_rows(excel_filepath)
2.munpy删除(34秒)
import win32com.client as win32
import numpy as np
# 创建Excel应用程序对象
excel = win32.Dispatch('ket.Application')
# 打开Excel文件
workbook = excel.Workbooks.Open(r"D:\SAP报表导出\序时账\新需求\merged2023-06-01 - 副本.xlsx")
# 设置Excel可见
excel.Visible = True
excel.DisplayAlerts = False
# 获取第一个工作表
worksheet = workbook.Worksheets(1)
# 读取所有数据
used_range = worksheet.UsedRange
data = used_range.Value
# 转换为numpy数组
np_data = np.array(data)
# 判断空行
empty_rows = np.where(np.all(np_data == None, axis=1))[0]
# 逆序删除空行
empty_rows = np.flip(empty_rows)
print(empty_rows)
# 删除空行
for row in empty_rows:
worksheet.Rows(row + 1).Delete()
# 保存并关闭Excel文件
workbook.Save()
workbook.Close()
# 退出Excel应用程序
excel.Quit()
通过使用win32com
库,你可以在Python中控制COM组件,包括启用或禁用Excel中的某个COM加载项。下面是一个示例代码,展示如何使用win32com
来启用或禁用Excel中的COM加载项:
import win32com.client as win32
def on_or_off_addin(flag='on'):
# 创建Excel Application实例
excel_app = win32.Dispatch("Excel.Application")
# 获取COM Add-ins集合
com_addins = excel_app.COMAddIns
excel_app.DisplayAlerts = False # 控制是否显示警告框
# 通过ProgID查找特定的COM Add-in
target_addin = None
for com_addin in com_addins:
if com_addin.ProgID == "WDF.Addin":
target_addin = com_addin
break
# 启用COM Add-in
if target_addin and flag == 'on':
target_addin.Connect = True
# 禁用COM Add-in
if target_addin and flag == 'off':
target_addin.Connect = False
# 退出Excel Application
excel_app.Quit()
# 测试启用COM Add-in
on_or_off_addin('on')
# 测试禁用COM Add-in
# on_or_off_addin('off')
在上面的代码中,你需要将"Your.Addin.ProgID"
替换为你想要启用或禁用的COM加载项的ProgID。然后,根据你想要启用还是禁用,你可以取消代码中注释的相应部分。
请注意,要运行此代码,你需要安装pywin32
(win32com.client
)库。你可以使用以下命令来安装:
pip install pywin32
此代码会在Python中创建一个Excel应用程序实例,然后通过COM Add-ins集合查找特定的COM加载项,并根据需要启用或禁用它。最后,记得在完成操作后关闭Excel应用程序。在实际操作中,请确保你明确了解你要启用或禁用的COM加载项的ProgID,并小心操作,以避免对Excel应用程序产生意外影响。
def get_column_letter(n):
string = ""
while n > 0:
n, remainder = divmod(n - 1, 26)
string = chr(65 + remainder) + string
return string
# 测试函数
print(get_column_letter(5)) # 输出: E
以下是关于如何使用 win32com
在 Excel 中设置特定字符的格式的详细文档:
2.17 使用 win32com
设置 Excel 单元格中特定字符的格式
在 Excel 中,我们经常需要对单元格中的特定字符应用不同的格式。使用 win32com
,我们可以通过 GetCharacters
方法来实现这一点。以下是如何在 Python 中使用 win32com
来设置 Excel 中特定字符的格式的步骤:
1. 安装 pywin32
包
首先,确保你已经安装了 pywin32
包。如果还没有安装,可以使用以下命令来安装:
pip install pywin32
2. 编写代码
以下是一个示例代码,演示了如何使用 win32com
设置 Excel 单元格中指定字符的格式:
import win32com.client
# 启动 Excel 应用程序
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True # 使 Excel 可见
# 打开一个工作簿
workbook = excel.Workbooks.Add()
sheet = workbook.Sheets(1)
# 向单元格 A1 中写入一些文本
cell = sheet.Cells(1, 1)
cell.Value = "Hello, World!"
# 设置特定字符的格式
start_pos = 1 # 起始字符位置
length = 5 # 字符长度
# 使用 GetCharacters 方法获取特定字符的对象
characters = cell.GetCharacters(start_pos, length)
# 设置字符的格式
characters.Font.Bold = True # 设置字符加粗
characters.Font.Italic = True # 设置字符斜体
characters.Font.ColorIndex = 3 # 设置字符颜色为红色(3 代表红色)
# 保存并关闭工作簿
workbook.SaveAs("formatted_text.xlsx")
workbook.Close()
# 退出 Excel 应用程序
excel.Quit()
3. 代码解释
- 启动 Excel 应用程序:使用
win32com.client.Dispatch
启动 Excel 应用程序并设置为可见。 - 打开一个工作簿:创建一个新的工作簿并获取第一个工作表。
- 向单元格写入文本:将文本 "Hello, World!" 写入单元格 A1。
- 设置特定字符的格式:通过
GetCharacters(start, length)
方法获取指定范围内的字符对象,并对这些字符的格式进行设置,如加粗、斜体、颜色等。 - 保存并关闭工作簿:将工作簿保存为 "formatted_text.xlsx" 并关闭它。
- 退出 Excel 应用程序:退出 Excel 应用程序以释放资源。
4. 注意事项
start_pos
和length
参数是基于 1 的索引,即第一个字符的位置是 1。Font.ColorIndex
使用的是 Excel 中的颜色索引,3 代表红色,你可以根据需要调整颜色索引。- 确保在操作完成后关闭 Excel 应用程序,以避免内存泄漏和资源浪费。
这个方法使你能够在 Excel 中灵活地设置文本格式,特别是在处理需要高亮显示或格式化特定文本的场景时非常有用。
你可以根据实际需求调整代码中的参数和格式设置。希望这个文档对你的工作有帮助!
3.office文件 (word, ppt, excel等) 转为pdf
#-*- coding:utf-8 -*-
import os
from win32com.client import Dispatch, constants, gencache, DispatchEx
class PDFConverter:
def __init__(self, pathname, export='.'):
self._handle_postfix = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
self._filename_list = list()
self._export_folder = os.path.join(os.path.abspath('.'), 'pdfconver')
if not os.path.exists(self._export_folder):
os.mkdir(self._export_folder)
self._enumerate_filename(pathname)
def _enumerate_filename(self, pathname):
'''
读取所有文件名
'''
full_pathname = os.path.abspath(pathname)
if os.path.isfile(full_pathname):
if self._is_legal_postfix(full_pathname):
self._filename_list.append(full_pathname)
else:
raise TypeError('文件 {} 后缀名不合法!仅支持如下文件类型:{}。'.format(pathname, '、'.join(self._handle_postfix)))
elif os.path.isdir(full_pathname):
for relpath, _, files in os.walk(full_pathname):
for name in files:
filename = os.path.join(full_pathname, relpath, name)
if self._is_legal_postfix(filename):
self._filename_list.append(os.path.join(filename))
else:
raise TypeError('文件/文件夹 {} 不存在或不合法!'.format(pathname))
def _is_legal_postfix(self, filename):
return filename.split('.')[-1].lower() in self._handle_postfix and not os.path.basename(filename).startswith('~')
def run_conver(self):
'''
进行批量处理,根据后缀名调用函数执行转换
'''
print('需要转换的文件数:', len(self._filename_list))
for filename in self._filename_list:
postfix = filename.split('.')[-1].lower()
funcCall = getattr(self, postfix)
print('原文件:', filename)
funcCall(filename)
print('转换完成!')
def doc(self, filename):
'''
doc 和 docx 文件转换
'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
print('保存 PDF 文件:', exportfile)
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)
w = Dispatch("Word.Application")
doc = w.Documents.Open(filename)
doc.ExportAsFixedFormat(exportfile, constants.wdExportFormatPDF,
Item=constants.wdExportDocumentWithMarkup,
CreateBookmarks=constants.wdExportCreateHeadingBookmarks)
w.Quit(constants.wdDoNotSaveChanges)
def docx(self, filename):
self.doc(filename)
def xls(self, filename):
'''
xls 和 xlsx 文件转换
'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
xlApp = DispatchEx("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = 0
books = xlApp.Workbooks.Open(filename,False)
books.ExportAsFixedFormat(0, exportfile)
books.Close(False)
print('保存 PDF 文件:', exportfile)
xlApp.Quit()
def xlsx(self, filename):
self.xls(filename)
def ppt(self, filename):
'''
ppt 和 pptx 文件转换
'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)
p = Dispatch("PowerPoint.Application")
ppt = p.Presentations.Open(filename, False, False, False)
ppt.ExportAsFixedFormat(exportfile, 2, PrintRange=None)
print('保存 PDF 文件:', exportfile)
p.Quit()
def pptx(self, filename):
self.ppt(filename)
if __name__ == "__main__":
# 支持文件夹批量导入
folder = 'tmp'
pathname = os.path.join(os.path.abspath('.'), folder)
# 也支持单个文件的转换
# pathname = 'test.doc'
pdfConverter = PDFConverter(pathname)
pdfConverter.run_conver()
方法二:
import win32com.client
# 创建Excel应用对象
excel = win32com.client.Dispatch("ket.Application")
# 打开Excel文件
wb = excel.Workbooks.Open('你的文件路径')
# 设置页面为纵向布局
wb.Worksheets[1].PageSetup.Orientation = 1
# 设置页面缩放以适应一页宽
wb.Worksheets[1].PageSetup.Zoom = False
wb.Worksheets[1].PageSetup.FitToPagesWide = 1
wb.Worksheets[1].PageSetup.FitToPagesTall = False
# 导出为PDF
wb.ExportAsFixedFormat(0, '你的PDF文件路径')
# 关闭工作簿和应用
wb.Close()
excel.Quit()
#-*- coding:utf-8 -*-
import os
from win32com.client import Dispatch, constants, gencache, DispatchEx
import xlrd
class PDFConverter:
def __init__(self, pathname,sheetnum, export='.'):
self.sheetnum = sheetnum
self._handle_postfix = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
self._filename_list = list()
self._export_folder = os.path.join(os.path.abspath('.'), 'pdfconver')
if not os.path.exists(self._export_folder):
os.mkdir(self._export_folder)
self._enumerate_filename(pathname)
def _enumerate_filename(self, pathname):
'''
读取所有文件名
'''
full_pathname = os.path.abspath(pathname)
if os.path.isfile(full_pathname):
if self._is_legal_postfix(full_pathname):
self._filename_list.append(full_pathname)
else:
raise TypeError('文件 {} 后缀名不合法!仅支持如下文件类型:{}。'.format(pathname, '、'.join(self._handle_postfix)))
elif os.path.isdir(full_pathname):
for relpath, _, files in os.walk(full_pathname):
for name in files:
filename = os.path.join(full_pathname, relpath, name)
if self._is_legal_postfix(filename):
self._filename_list.append(os.path.join(filename))
else:
raise TypeError('文件/文件夹 {} 不存在或不合法!'.format(pathname))
def _is_legal_postfix(self, filename):
return filename.split('.')[-1].lower() in self._handle_postfix and not os.path.basename(filename).startswith(
'~')
def run_conver(self):
'''
进行批量处理,根据后缀名调用函数执行转换
'''
print('需要转换的文件数:', len(self._filename_list))
for filename in self._filename_list:
postfix = filename.split('.')[-1].lower()
funcCall = getattr(self, postfix)
print('原文件:', filename)
funcCall(filename)
print('转换完成!')
def xls(self, filename):
'''
xls 和 xlsx 文件转换
'''
xlApp = DispatchEx("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = 0
books = xlApp.Workbooks.Open(filename, False)
# 循环保存每一个sheet
for i in range(1, self.sheetnum+1):
sheetName = books.Sheets(i).Name
xlSheet = books.Worksheets(sheetName)
name = sheetName + '.pdf'
exportfile = os.path.join(self._export_folder, name)
xlSheet.ExportAsFixedFormat(0, exportfile)
print('保存 PDF 文件:', exportfile)
books.Close(False)
xlApp.Quit()
def xlsx(self, filename):
self.xls(filename)
if __name__ == "__main__":
# 支持单个文件的转换
pathname = u'原始数据.xlsx'
# 获取到文件的sheet数
b = xlrd.open_workbook(pathname)
sheetnum = len(b.sheets())
pdfConverter = PDFConverter(pathname, sheetnum)
pdfConverter.run_conver()
模块安装
pip install python-pptx
slide(幻灯片):一个PPT由一系列slide构成。
slide_master(幻灯片母版):母版可定义主题样式基准。
slide_layouts(模版):创建幻灯片时可选择的模版。
shape(形状):包含一切可视元素,通过slide.shapes可访问slide内元素。
placeholder(占位符):在模板中占据位置,如图片、文字等。
paragraph(段落):文本段,可以直接设置整段文本样式。
text(文本):段落内的文本,通过paragraph.add_run()生成。
获取Slide(每一张幻灯片)
from pptx import Presentation
ppt_path = r"C:\Users\yys53\Desktop\222.pptx"
prs = Presentation(ppt_path)
for slide in prs.slides:
print(slide)
出现报错
KeyError: "There is no item named 'ppt/slides/NULL' in the archive"
解决,修改源码C:\Users\yys53\OneDrive\python\install\Lib\site-packages\pptx\opc\pkgreader.py
def load_from_xml(baseURI, rels_item_xml):
"""
Return |_SerializedRelationshipCollection| instance loaded with the
relationships contained in *rels_item_xml*. Returns an empty
collection if *rels_item_xml* is |None|.
"""
srels = _SerializedRelationshipCollection()
if rels_item_xml is not None:
rels_elm = parse_xml(rels_item_xml)
for rel_elm in rels_elm.relationship_lst:
srels._srels.append(_SerializedRelationship(baseURI, rel_elm))
return srels
↓↓↓↓↓↓↓↓↓↓修改为 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
def load_from_xml(baseURI, rels_item_xml):
"""
Return |_SerializedRelationshipCollection| instance loaded with the
relationships contained in *rels_item_xml*. Returns an empty
collection if *rels_item_xml* is |None|.
"""
srels = _SerializedRelationshipCollection()
if rels_item_xml is not None:
if 'NULL' in str(rels_item_xml):
print('NULL found and skiped')
pass
else:
rels_elm = parse_xml(rels_item_xml)
for rel_elm in rels_elm.relationship_lst:
srels._srels.append(_SerializedRelationship(baseURI, rel_elm))
return srels
获取Shape形状(方框)
from pptx import Presentation
ppt_path = r"C:\Users\yys53\OneDrive\终极数学题.pptx"
prs = Presentation(ppt_path)
for slide in prs.slides:
for shape in slide.shapes:
print(shape)
判断每个Shape中是否存在文字
- shape.has_text_frame :是否有文字
- shape.text_frame :获取文字框
from pptx import Presentation
ppt_path = r"C:\Users\yys53\OneDrive\终极数学题.pptx"
prs = Presentation(ppt_path)
for slide in prs.slides:
for shape in slide.shapes:
if shape.has_text_frame:
text_frame = shape.text_frame
print(text_frame.text)
来自 https://blog.csdn.net/weixin_41261833/article/details/106406229
本文作者: 永生
本文链接: https://yys.zone/detail/?id=154
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!