InDesignの表組を直接Excelにコピペしたら、とんでもない結果になる。セルの結合状態と数値だけをエクセル表組に変換したい場合は、(プログラムが)わりと簡単にできてしまう。
Github: 14_export_table_to_Excel.py
"""
注意:セルの結合状態と文字のみを再現、その他のもの(例:画像、インラインテキストフレーム、セル内の表組、色、罫線等)は全て無視
"""
import xlwings as xw
from appscript import app, k
indd = app("Adobe InDesign 2022")
class Table():
def __init__(self, row_count: int, column_count: int, cell_datas: list):
self.row_count = row_count
self.column_count = column_count
self.cell_datas = cell_datas
def get_info_from_indesign_table():
if len(indd.selection()) == 0:
print("please select a table or a text_frame containing a table")
return
sel = indd.selection()[0] # text_frame or table
class_ = sel.class_()
if class_ == k.table:
tables = [sel]
elif class_ == k.text_frame:
tables = sel.tables()
else:
print("Not a table nor a text_frame")
return
table_objs = []
for table in tables:
cell_datas = []
cells = table.cells
for cell in cells():
c, r = [int(x) for x in cell.name().split(":")]
cell_datas.append({
"column": c,
"row": r,
"column_span": cell.column_span(),
"row_span": cell.row_span(),
# indesignの改行をエクセル改行記号に
"contents": cell.contents().replace("\r", "\n") # TODO: セルの溢れは要処理
})
table_objs.append(
Table(len(table.rows()), len(table.columns()), cell_datas)
)
return table_objs
def generate_excel_table(table_objs, wb=None, sh=None, start_cell_row=1, start_cell_column=1):
# 開始セル: default(1,1) --> A1 cell
if not wb:
wb = xw.Book() # add a new book
# wb = xw.books[0] # current active book
wb.activate(steal_focus=True)
if not sh: # adcive sheet
sh = wb.sheets.active
for table in table_objs:
offset_row = start_cell_row - table.cell_datas[0]["row"]
offset_column = start_cell_column - table.cell_datas[0]["column"]
for x in table.cell_datas:
r, c = x["row"] + offset_row, x["column"] + offset_column
sh.cells(r, c).value = x["contents"]
sh.cells(r, c).api.wrap_text.set(True)
r_span, c_span = x["row_span"], x["column_span"]
if c_span != 1 or r_span != 1: # セル結合必要な場合
sh.range((r, c), (r + r_span - 1, c + c_span - 1)).merge()
# set border
end_cell_rc = (start_cell_row + table.row_count - 1,
start_cell_column + table.column_count - 1)
for border in [k.border_top, k.border_bottom, k.border_left, k.border_right]:
sh.range((start_cell_row, start_cell_column), end_cell_rc
).api.get_border(which_border=border).weight.set(2)
#
# 1InDesignテキストフレームに複数の表組がある場合、上から下へ配置
start_cell_row = start_cell_row + table.row_count + 1 # 空行1行を確保
# 左から右へ配置
# start_cell_column = start_cell_column + table.column_count + 1
if __name__ == "__main__":
table_objs = get_info_from_indesign_table()
if table_objs:
generate_excel_table(table_objs)
