如何使用 Python 从 Excel 图表表打印图表
How to print a chart from an Excel Chartsheet using Python
我完全不熟悉编码(这只是为了好玩,希望能节省一些工作时间)并且我一直在努力使我的第一行代码正常工作。
具体来说,我希望我的代码打开某个 Excel 工作簿,找到某些实际上是图表的工作表(每个工作表中只有一个图表)并将它们打印为特定文件夹中的 pdf/jpeg 文件。我选择了 ExportAsFixedFormat,但遇到了以下错误。
AttributeError: 'Chartsheet' object has no attribute 'ExportAsFixedFormat'
你能帮帮我吗?有什么方法可以 print/save 图表表吗?
我查看了 Chartsheet 对象的方法,但找不到任何有用的信息。我确定我遗漏了什么。
关于我的配置的一些信息:
Windows 10 家 x64
Excel Microsoft 365 MSO (16.0.13628.20318) 64 位
Python 3.8 32 位
Pywin32 版本 227
下面是我遇到问题的代码块。
[编辑]:下面是我写的全部代码,可能错误不在我想的地方。
提前谢谢你,抱歉我的英语不好。
首先,我导入了很多东西,我知道我很可能只需要一半。
import plotly
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import win32com.client as win32
import openpyxl
import os, sys
import math
import openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl import chart
from openpyxl import chartsheet
from openpyxl.chartsheet.publish import WebPublishItem, WebPublishItems
from openpyxl.drawing.spreadsheet_drawing import SpreadsheetDrawing
#from .drawings import find_images
from openpyxl.chartsheet import Chartsheet
import openpyxl.chart
import win32com.client
from pdf2image import convert_from_path
from pathlib import Path
import xlsxwriter
这是我写的代码:
path_filePy = Path(__file__).resolve()
current_folder = path_filePy.parent
image_folder_name = "Immages"
image_folder_path = os.path.join(current_folder, image_folder_name)
try:
os.mkdir(image_folder_path)
except OSError:
files = os.listdir(image_folder_path)
for f in files:
os.remove(image_folder_path + '\'+ f)
folder_list = os.listdir(current_folder)
excel_list=[]
for l in folder_list:
if l.endswith('.xlsx'):
excel_list.append(l)
chartsheets_names=['Chartsheet1', 'Chartsheet2', 'Chartsheet3', 'Chartsheet4']
excel = win32.gencache.EnsureDispatch('Excel.Application')
for excelfile in excel_list:
wb = load_workbook(os.path.join(current_folder, excelfile))
for sheet in chartsheets_names:
ws=wb[sheet]
image_file_name = excelfile[:-5]+'_'+sheet+'.pdf'
image_file_path = os.path.join(image_folder_path,image_file_name)
ws.ExportAsFixedFormat(0, image_file_path)
convert_from_path(image_file_path, dpi=300, output_folder=image_folder_path,fmt='jpeg')
wb.Close()
请参阅更新后的答案。
请参阅下面的进一步更新。
在 pip install comtypes
之后这对我有用:
import os
import comtypes.client
SOURCE_DIR = r'C:\Users\xyz\SO-samples' # adjust to your needs
TARGET_DIR = r'C:\Users\xyz\SO-samples' # adjust to your needs
app = comtypes.client.CreateObject('Excel.Application')
app.Visible = False
infile = os.path.join(os.path.abspath(SOURCE_DIR), 'an-excel-file.xlsx')
outfile = os.path.join(os.path.abspath(TARGET_DIR), 'an-excel-file.pdf')
doc = app.Workbooks.Open(infile)
doc.ExportAsFixedFormat(0, outfile, 1, 0)
doc.Close()
app.Quit()
更新的答案 - select可用 sheets:
import os
import win32com.client
SOURCE_DIR = r'C:\Users\xyz\SO-samples' # adjust
TARGET_DIR = r'C:\Users\xyz\SO-samples' # adjust
wb_path = os.path.join(os.path.abspath(SOURCE_DIR), 'xyzzy.xlsx')
wb = o.Workbooks.Open(wb_path)
o = win32com.client.Dispatch("Excel.Application")
o.Visible = False
# print 1 sheet to 1 file
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy2.pdf')
ws_index_list = [2] # say you want to print this sheet
wb.WorkSheets(ws_index_list).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# print 2 sheets to 1 file
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-1-3.pdf')
ws_index_list = [1,3] # say you want to print these sheets
wb.WorkSheets(ws_index_list).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# print 3 sheets to 1 file each
ws_index_list = [1,2,3] # say you want to print these sheets
for ws_index in ws_index_list:
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-' + str(ws_index) + '.pdf')
wb.WorkSheets([ws_index]).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# select sheet by name, print 1 sheet to 1 file
ws_sheet_name = 'named_sheet'
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-' + ws_sheet_name + '.pdf')
wb.WorkSheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
进一步更新 - 按名称打印 sheet 姓名,select sheet:
import win32com.client as w3c
import os, sys
SOURCE_DIR = r'C:\Users\xyz\SO-samples'
TARGET_DIR = r'C:\Users\xyz\SO-samples'
wb_path = os.path.join(os.path.abspath(SOURCE_DIR), 'xyzzy.xlsx')
o = w3c.Dispatch("Excel.Application")
o.Visible = False
wb = o.Workbooks.Open(wb_path)
for wb_sheet in wb.Sheets:
print(wb_sheet.Name)
### this works
ws_sheet_name = [1,3]
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy' + '.pdf')
wb.Worksheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
### this works
ws_sheet_name = 'xyzzy'
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-xyzzy' + '.pdf')
wb.Worksheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
wb.Close()
我终于如愿以偿了。下面是我现在使用的代码,也许对其他人也有帮助。
我想我在搞乱与 win32com 相关的代码和与 openpxl 相关的代码。
现在我希望我的 Chartsheets 在打印之前拉伸整个打印区域(我试图将边距设置为零,但它不起作用)。我想我应该使用 wb_sheet.PageSetup.ChartSize
和值 FullPage
,但我不知道如何分配它。
import os
import sys
from pathlib import Path
import win32com.client as w3c
from pdf2image import convert_from_path
# find the parent folder of the .py file
path_filePy = Path(__file__).resolve()
current_folder = path_filePy.parent
print(current_folder)
# create the destination folder or empty it if existing
image_folder_name = "Immages"
image_folder_path = os.path.join(current_folder, image_folder_name)
#print(image_folder_path)
try:
os.mkdir(image_folder_path)
except OSError:
files = os.listdir(image_folder_path)
for f in files:
os.remove(image_folder_path + '\'+ f)
# list of file in the folder
folder_list = os.listdir(current_folder)
# list of only *.xlsx files
excel_list=[]
for l in folder_list:
if l.endswith('.xlsx'):
excel_list.append(l)
# listof sheets' names I want to print
chartsheets_names=['Sheet1', 'Sheet2', 'Sheet3', 'Sheet4']
o = w3c.Dispatch("Excel.Application")
o.Visible = False
# for each sheet names as in my list, in each xlsx file, it prints in both pdf and jpeg
for excel_file in excel_list:
try:
wb_path = os.path.join(os.path.abspath(current_folder), excel_file)
wb = o.Workbooks.Open(wb_path)
for wb_sheet in wb.Sheets:
if wb_sheet.Name in chartsheets_names:
path_to_pdf = os.path.join(os.path.abspath(image_folder_path), excel_file[:-5] + ' - ' + str(wb_sheet.Name) + '.pdf')
wb_sheet.SaveAs(path_to_pdf, FileFormat=57)
convert_from_path(
path_to_pdf, # the input pdf file
dpi=300,
output_folder=image_folder_path,
fmt='jpeg',
output_file=str(excel_file[:-5] + ' - ' + str(wb_sheet.Name)),
poppler_path = r"C:\where\your\poppler\bin folder is",
use_pdftocairo=False)
else: next
wb.Close(False)
except OSError:
next
o.Quit
`
我完全不熟悉编码(这只是为了好玩,希望能节省一些工作时间)并且我一直在努力使我的第一行代码正常工作。
具体来说,我希望我的代码打开某个 Excel 工作簿,找到某些实际上是图表的工作表(每个工作表中只有一个图表)并将它们打印为特定文件夹中的 pdf/jpeg 文件。我选择了 ExportAsFixedFormat,但遇到了以下错误。
AttributeError: 'Chartsheet' object has no attribute 'ExportAsFixedFormat'
你能帮帮我吗?有什么方法可以 print/save 图表表吗?
我查看了 Chartsheet 对象的方法,但找不到任何有用的信息。我确定我遗漏了什么。
关于我的配置的一些信息:
Windows 10 家 x64
Excel Microsoft 365 MSO (16.0.13628.20318) 64 位
Python 3.8 32 位
Pywin32 版本 227
下面是我遇到问题的代码块。
[编辑]:下面是我写的全部代码,可能错误不在我想的地方。
提前谢谢你,抱歉我的英语不好。
首先,我导入了很多东西,我知道我很可能只需要一半。
import plotly
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import win32com.client as win32
import openpyxl
import os, sys
import math
import openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl import chart
from openpyxl import chartsheet
from openpyxl.chartsheet.publish import WebPublishItem, WebPublishItems
from openpyxl.drawing.spreadsheet_drawing import SpreadsheetDrawing
#from .drawings import find_images
from openpyxl.chartsheet import Chartsheet
import openpyxl.chart
import win32com.client
from pdf2image import convert_from_path
from pathlib import Path
import xlsxwriter
这是我写的代码:
path_filePy = Path(__file__).resolve()
current_folder = path_filePy.parent
image_folder_name = "Immages"
image_folder_path = os.path.join(current_folder, image_folder_name)
try:
os.mkdir(image_folder_path)
except OSError:
files = os.listdir(image_folder_path)
for f in files:
os.remove(image_folder_path + '\'+ f)
folder_list = os.listdir(current_folder)
excel_list=[]
for l in folder_list:
if l.endswith('.xlsx'):
excel_list.append(l)
chartsheets_names=['Chartsheet1', 'Chartsheet2', 'Chartsheet3', 'Chartsheet4']
excel = win32.gencache.EnsureDispatch('Excel.Application')
for excelfile in excel_list:
wb = load_workbook(os.path.join(current_folder, excelfile))
for sheet in chartsheets_names:
ws=wb[sheet]
image_file_name = excelfile[:-5]+'_'+sheet+'.pdf'
image_file_path = os.path.join(image_folder_path,image_file_name)
ws.ExportAsFixedFormat(0, image_file_path)
convert_from_path(image_file_path, dpi=300, output_folder=image_folder_path,fmt='jpeg')
wb.Close()
请参阅更新后的答案。 请参阅下面的进一步更新。
在 pip install comtypes
之后这对我有用:
import os
import comtypes.client
SOURCE_DIR = r'C:\Users\xyz\SO-samples' # adjust to your needs
TARGET_DIR = r'C:\Users\xyz\SO-samples' # adjust to your needs
app = comtypes.client.CreateObject('Excel.Application')
app.Visible = False
infile = os.path.join(os.path.abspath(SOURCE_DIR), 'an-excel-file.xlsx')
outfile = os.path.join(os.path.abspath(TARGET_DIR), 'an-excel-file.pdf')
doc = app.Workbooks.Open(infile)
doc.ExportAsFixedFormat(0, outfile, 1, 0)
doc.Close()
app.Quit()
更新的答案 - select可用 sheets:
import os
import win32com.client
SOURCE_DIR = r'C:\Users\xyz\SO-samples' # adjust
TARGET_DIR = r'C:\Users\xyz\SO-samples' # adjust
wb_path = os.path.join(os.path.abspath(SOURCE_DIR), 'xyzzy.xlsx')
wb = o.Workbooks.Open(wb_path)
o = win32com.client.Dispatch("Excel.Application")
o.Visible = False
# print 1 sheet to 1 file
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy2.pdf')
ws_index_list = [2] # say you want to print this sheet
wb.WorkSheets(ws_index_list).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# print 2 sheets to 1 file
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-1-3.pdf')
ws_index_list = [1,3] # say you want to print these sheets
wb.WorkSheets(ws_index_list).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# print 3 sheets to 1 file each
ws_index_list = [1,2,3] # say you want to print these sheets
for ws_index in ws_index_list:
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-' + str(ws_index) + '.pdf')
wb.WorkSheets([ws_index]).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
# select sheet by name, print 1 sheet to 1 file
ws_sheet_name = 'named_sheet'
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-' + ws_sheet_name + '.pdf')
wb.WorkSheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
进一步更新 - 按名称打印 sheet 姓名,select sheet:
import win32com.client as w3c
import os, sys
SOURCE_DIR = r'C:\Users\xyz\SO-samples'
TARGET_DIR = r'C:\Users\xyz\SO-samples'
wb_path = os.path.join(os.path.abspath(SOURCE_DIR), 'xyzzy.xlsx')
o = w3c.Dispatch("Excel.Application")
o.Visible = False
wb = o.Workbooks.Open(wb_path)
for wb_sheet in wb.Sheets:
print(wb_sheet.Name)
### this works
ws_sheet_name = [1,3]
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy' + '.pdf')
wb.Worksheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
### this works
ws_sheet_name = 'xyzzy'
path_to_pdf = os.path.join(os.path.abspath(TARGET_DIR), 'xyzzy-xyzzy' + '.pdf')
wb.Worksheets(ws_sheet_name).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, path_to_pdf)
wb.Close()
我终于如愿以偿了。下面是我现在使用的代码,也许对其他人也有帮助。 我想我在搞乱与 win32com 相关的代码和与 openpxl 相关的代码。
现在我希望我的 Chartsheets 在打印之前拉伸整个打印区域(我试图将边距设置为零,但它不起作用)。我想我应该使用 wb_sheet.PageSetup.ChartSize
和值 FullPage
,但我不知道如何分配它。
import os
import sys
from pathlib import Path
import win32com.client as w3c
from pdf2image import convert_from_path
# find the parent folder of the .py file
path_filePy = Path(__file__).resolve()
current_folder = path_filePy.parent
print(current_folder)
# create the destination folder or empty it if existing
image_folder_name = "Immages"
image_folder_path = os.path.join(current_folder, image_folder_name)
#print(image_folder_path)
try:
os.mkdir(image_folder_path)
except OSError:
files = os.listdir(image_folder_path)
for f in files:
os.remove(image_folder_path + '\'+ f)
# list of file in the folder
folder_list = os.listdir(current_folder)
# list of only *.xlsx files
excel_list=[]
for l in folder_list:
if l.endswith('.xlsx'):
excel_list.append(l)
# listof sheets' names I want to print
chartsheets_names=['Sheet1', 'Sheet2', 'Sheet3', 'Sheet4']
o = w3c.Dispatch("Excel.Application")
o.Visible = False
# for each sheet names as in my list, in each xlsx file, it prints in both pdf and jpeg
for excel_file in excel_list:
try:
wb_path = os.path.join(os.path.abspath(current_folder), excel_file)
wb = o.Workbooks.Open(wb_path)
for wb_sheet in wb.Sheets:
if wb_sheet.Name in chartsheets_names:
path_to_pdf = os.path.join(os.path.abspath(image_folder_path), excel_file[:-5] + ' - ' + str(wb_sheet.Name) + '.pdf')
wb_sheet.SaveAs(path_to_pdf, FileFormat=57)
convert_from_path(
path_to_pdf, # the input pdf file
dpi=300,
output_folder=image_folder_path,
fmt='jpeg',
output_file=str(excel_file[:-5] + ' - ' + str(wb_sheet.Name)),
poppler_path = r"C:\where\your\poppler\bin folder is",
use_pdftocairo=False)
else: next
wb.Close(False)
except OSError:
next
o.Quit
`