pythonでエクセルの表をコピーしてパワポに貼り付けるプログラムを作ってみました。
本当は文字と上下左右中央寄せもコピーしたかったけど疲れたでここで
openpyxlで特定の範囲で下記情報をコピー
・テキスト
・背景塗りつぶし色
・文字色
・太字情報
・セルのマージ情報
・不完全だけど表サイズ
excel_to_pptxtable.py
import openpyxl
from openpyxl.styles import PatternFill, Font, Border
from openpyxl.utils import get_column_letter
import sys
def excel_get_cell_info(sheet, cellkey):
'''
cell情報を返す ( sheet , "B4" )
#cell_obj = sheet["B2"] sheet["B2"].column_letter
#cell_obj = sheet.cell(row=2, column=2)
'''
cell_obj = sheet[cellkey]
# 塗りつぶし色
fill_color = cell_obj.fill.start_color.index if cell_obj.fill else None
# COLOR = "AARRGGBB" AA:不透明度00なら透明、RR:赤、GG:緑、BB:青
if fill_color[0:2] == '00' or fill_color == None :
font_color = '00FFFFFF'
# 文字色
font_color = cell_obj.font.color.index if cell_obj.font.color else None
if font_color == 1 or font_color == None :
font_color = '00000000'
font_bold = cell_obj.font.bold
# 枠線の有無
borders = cell_obj.border
border_info = {
'top': bool(borders.top),
'bottom': bool(borders.bottom),
'left': bool(borders.left),
'right': bool(borders.right),
}
# セルマージ情報
merged_cells = sheet.merged_cells
merged_range = [m.bounds for m in merged_cells if cellkey == str(m).split(":")[0]]
if len(merged_range) > 0:
#for m in merged_cells:
# print(str(m),cellkey == str(m).split(":")[0])
ll = merged_range[0]
#print("merged",ll[2] - ll[0],ll[3] - ll[1])
# セルの値を取得
value = cell_obj.value
# 計算式の場合は計算結果を取得
#if cell_obj.data_type == 'f': # 'f' は計算式を示す
# formula_result = cell_obj.value # 計算式の結果
# { 'type': 'formula', 'value': formula_result }
# 文字列または数値の場合
#if isinstance(value, (str, int, float)):
# { 'type': 'value', 'value': value }
return {
'fill_color': fill_color,
'font_color': font_color,
'font_bold' : font_bold,
'value':value,
'merged_range':merged_range,
#'border_info': border_info,
}
#enddef excel_get_cell_info
def tuple_to_a1(row, column):
## 使用例
##print(tuple_to_a1(3, 3)) # 出力: "C3"
# 行番号を文字列に変換
if row == 0 or column == 0 :
print("excel row col >= 0",row,column)
sys.exit()
row_number = str(row)
# 列番号を文字列に変換
column_letter = ""
while column > 0:
column -= 1
column_letter = chr(column % 26 + ord('A')) + column_letter
column //= 26
#
return column_letter + row_number
#enddef
def excel_get_table_info(sheet, sr , sc , rowr , colr ):
'''
sheet:sheet
sr:スタート行
sc:スタート列
rowr:読み込む行範囲
colr:読み込む列範囲
'''
retcsv = []
# 1行目、2行目、3行目と読んでいく
for row_idy in range(sr,sr+rowr) :
row = []
# 1列目、2列目、3列目と
for col_idx in range(sc,sc+colr) :
cellkey = tuple_to_a1(row_idy,col_idx)
#print("debug",cellkey,"row",row_idy,"col",col_idx)
row.append( excel_get_cell_info(sheet, cellkey) )
retcsv.append(row)
#endfor
# セルマージ情報print
print("## cell marge start")
for mr in sheet.merged_cells.ranges :
print(mr)
print(mr.bounds)
#endfor
print("## cell marge end")
# セルの幅(文字数)と高さ(ポイント)で取得※文字数×7=ポイント
pwidth = 0
pheight = 0
for rn in range( sr + rowr ) :
pwidth += sheet.column_dimensions[get_column_letter(rn+1)].width
for rn in range( sc + colr ) :
pheight += sheet.row_dimensions[rn+1].height
return retcsv , pwidth , pheight
#enddef
#############################
from pptx import Presentation
from pptx.util import Inches
from pptx.dml.color import RGBColor
from pptx.oxml.xmlchemy import OxmlElement
## https://stackoverflow.com/questions/42610829/python-pptx-changing-table-style-or-adding-borders-to-cells
def SubElement(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def _set_cell_border(cell, border_color="000000", border_width='12700'):
linStyle = 'solid'
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
for lines in ['a:lnL','a:lnR','a:lnT','a:lnB']:
ln = SubElement(tcPr, lines, w=border_width, cap='flat', cmpd='sng', algn='ctr')
solidFill = SubElement(ln, 'a:solidFill')
srgbClr = SubElement(solidFill, 'a:srgbClr', val=border_color)
prstDash = SubElement(ln, 'a:prstDash', val=linStyle) ## 線のスタイル
round_ = SubElement(ln, 'a:round')
headEnd = SubElement(ln, 'a:headEnd', type='none', w='med', len='med')
tailEnd = SubElement(ln, 'a:tailEnd', type='none', w='med', len='med')
'''
ppt_table_cell_font
pptxのテーブルのcellの文字色、太字の有無の設定
'''
def ppt_table_cell_font(cell,color=(0,0,0),bold=False):
for paragraph in cell.text_frame.paragraphs: # 段落のループ
for run in paragraph.runs: # 文字のループ
run.font.color.rgb = RGBColor(*color) # 黒色に設定
run.font.bold = bold # 太字を解除
#enddef
'''
ppt_table_reset
pptxのテーブルを一律設定
黒枠設定、塗りつぶし無し、文字色黒、太字無し
'''
def ppt_table_reset(table):
num_rows = len(table.rows)
num_cols = len(table.columns)
for row in range(num_rows):
for col in range(num_cols):
cell = table.cell(row, col)
# セル背景塗りつぶし
cell.fill.solid()
cell.fill.fore_color.rgb = RGBColor(255, 255, 255) # 白色
cell.fill.background() ##noFill
# 線の設定
_set_cell_border(table.cell(row, col))
# 文字の設定
ppt_table_cell_font(cell, (0,0,0),False)
#enddef
#############################
'''
argb_to_rgb('AARRGGBB')
AA は透明度
RGBを(129,44,00) みたいなのに変換
'''
def argb_to_rgb(argb_color):
# 先頭の2文字を除去してRGBを取得
alfa = int(argb_color[0:2],16)
red = int(argb_color[2:4],16)
green = int(argb_color[4:6],16)
blue = int(argb_color[6:8],16)
return (red, green, blue) , alfa
#enddef
'''
etcsv_to_ppt_table
エクセルから取得したtable情報をpptのテーブルで作成
'''
def etcsv_to_ppt_table( etcsv , slide ,pwidth,pheight) :
# テーブルの作成
rows, cols = len(etcsv),len(etcsv[0]),
left = Inches(1)
top = Inches(1)
width = Inches(pwidth*3/73) # エクセルのwidthは文字数なのでpointに変換するために2~7×
height = Inches(pheight/73)
table = slide.shapes.add_table(rows,cols, left, top, width, height).table
ppt_table_reset(table)
#print("debug range",rows,cols)
# 1行目、2行目、3行目と読んでいく
for row in range(rows):
for col in range(cols):
ptablecell = table.cell(row,col,)
etcell = etcsv[row][col]
# value
if etcell['value'] != None :
ptablecell.text = etcell['value']
#print("debug","r",row,"c",col,"value",etcell['value'])
# y行x列をマージ
merge_cell = etcell['merged_range']
if len(merge_cell) > 0:
merge_cell_range = merge_cell[0]
mergeend_col = col + merge_cell_range[2]-merge_cell_range[0] # +1
mergeend_row = row + merge_cell_range[3]-merge_cell_range[1] # +1
#print("debug","r",row,"c",col,"merge","mr",mergeend_row,"mc",mergeend_col)
ptablecell.merge(table.cell(mergeend_row,mergeend_col,))
# セル背景塗りつぶし
if etcell['fill_color'][0:2] != '00' :
ptablecell.fill.solid()
#ptablecell.fill.background() ##noFill
fcolor , alfa = argb_to_rgb(etcell['fill_color'])
ptablecell.fill.fore_color.rgb = RGBColor( *fcolor ) ## 塗りつぶし
# 文字の設定
fcolor , alfa = argb_to_rgb(etcell['font_color'])
ppt_table_cell_font(ptablecell,fcolor,etcell['font_bold'])
#############
if __name__ == '__main__':
# 使用例
file_path = 'sss2.xlsx' # Excelファイルのパス
# Excelファイルを読み込む
wb = openpyxl.load_workbook(file_path)
print("## sheetname start")
for sname in wb.sheetnames :
print(sname)
print("## sheetname end")
# 指定した範囲をコピー
# sheets,sr行,sc列,rowr行,colr列
# B2:E10 , (2,2)-(5-9) , (2,2)->[4,8]
excellinfo_csv ,pwidth ,pheight = excel_get_table_info(wb['22'],2,2,8,4)
if False : # debug
for row_idy , valy in enumerate(excellinfo_csv) :
for col_idx , val in enumerate(valy) :
print( row_idy , col_idx , val )
# プレゼンテーションを作成
prs = Presentation()
# スライドを追加
slide_layout = prs.slide_layouts[5] # 空白のスライド
slide = prs.slides.add_slide(slide_layout)
# エクセルからコピーしてきたデータをスライドに張り付け
etcsv_to_ppt_table(excellinfo_csv,slide,pwidth,pheight)
# プレゼンテーションを保存
prs.save('table_presentation.pptx')