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)