LoginSignup
9
5

draw.ioの全ページを一括変換する

Last updated at Posted at 2021-03-09

はじめに

draw.ioで作成した図の全ページを一括で画像ファイルに変換する方法をまとめました。

実行環境

  • Windows 10 Pro
    • バージョン22H2
  • drawio-desktop
    • v 22.1.2
  • Python
    • 3.12.0 64bit

実装

ディレクトリ構成

drawioフォルダ内にある.drawioファイルからimageフォルダに.svgを作成します。
出力されるファイル名は{file_name}-{page_name}.svgになります

./
│  make.py
├─drawio # 入力
│      sample1.drawio
│      sample2.drawio
└─image # 出力
        sample1-page-1.svg
        sample1-page-2.svg
        sample2-page 1.svg
        sample2-page 2.svg

コード

make.py
from pathlib import Path
import subprocess
import xml.etree.ElementTree as et

DRAWIO_PATH = '"C:\Program Files\draw.io\draw.io.exe"'
ROOT_DIR = Path(__file__).resolve().parent
INPUT_DIR = ROOT_DIR / "drawio"
OUTPUT_DIR = ROOT_DIR / "image"

def generate_image(input_path : Path):

    try:
        root = et.parse(str(input_path)).getroot()
    except et.ParseError:
        print(f"Error : Failed to parse XML file {input_path}")
        return

    # 1ページの場合pagesが存在しないのでデフォルトを1とする。
    pages = int(root.get("pages", 1))

    for page in range(pages):
        page_name = root[page].get("name")
        output_file_name = f"{input_path.stem}-{page_name}.svg"
        output_path = OUTPUT_DIR / output_file_name

        command = f'{DRAWIO_PATH} "{input_path}" -x -f svg -p {page} -o "{output_path}"'

        try:
            subprocess.run(command, check=True)
        except subprocess.CalledProcessError:
            print(f'Error : Failed to execute "{command}"')

if __name__ == "__main__":

    OUTPUT_DIR.mkdir(exist_ok=True)

    for file_path in INPUT_DIR.glob("*.drawio"):
        generate_image(file_path)
旧コード
make.py
from pathlib import Path
import xml.etree.ElementTree as et
import subprocess


def get_output_path(file_path, page_name, file_type):
    stem = '-'.join([str(file_path.stem), page_name])
    suffix = '.' + file_type
    return file_path.with_name(stem).with_suffix(suffix)


def generate_image(file_path):
    DRAWIO = '"C:\Program Files\draw.io\draw.io.exe"'
    FILE_TYPE = 'svg'

    root = et.parse(file_path).getroot()

    for i in range(int(root.get('pages'))):
        page_name = root[i].get('name')
        # option
        f = ' '.join(['-f', FILE_TYPE])
        p = ' '.join(['-p', str(i)])
        o = ' '.join(['-o', '"' + str(get_output_path(file_path, page_name, FILE_TYPE)) + '"'])
        # run
        command = ' '.join([DRAWIO, '"' + str(file_path) + '"', '-x', f, p, o])
        subprocess.run(command)


if __name__ == '__main__':
    root_dir = Path.cwd()
    for i in root_dir.glob('image\\*.drawio'):
        generate_image(i.relative_to(root_dir))

解説

.drawioの読み出し

以下のように.drawioファイル内にはページ数pagesと各ページの名前nameの情報があります。
これをxml.etree.ElementTreeで読み出してファイル名を生成しています。

sample1.drawio
<mxfile modified="..." ... pages="3">
	<diagram name="page1" id="...">
	    ...
	</diagram>
	<diagram name="page2" id="...">
        ...
    </diagram>
	<diagram name="page3" id="...">
        ...
    </diagram>
</mxfile>

python上ではファイル毎にpagesの数だけ生成処理を行います。

    try:
        root = et.parse(str(input_path)).getroot()
    except et.ParseError:
        print(f"Error : Failed to parse XML file {input_path}")

    # 1ページの場合pagesが存在しないのでデフォルトを1とする。
    pages = int(root.get("pages", 1))

    for page in range(pages):
        page_name = root[page].get("name")

.drawioファイルの各ページの生成方法

drawioをコマンドライン実行する方法はdraw.io をコマンドラインで実行して、画像ファイルをエクスポートするが参考になります。

-p, --page-index <pageIndex>で指定したページを変換することができます。

-a, --all-pagesはpdf生成のみ対応しているため、画像生成時は使用できないので注意しましょう。

例えば1ページ目を生成する時は以下のようになります。

コマンド
"C:\Program Files\draw.io\draw.io.exe" "image/sample1.drawio" -x -f svg -p 0 -o "image/sample1-page1.svg"

その他

ファイル名やページ名に空白が含まれる可能性があるため、pathは""で囲うようにしています。

        command = f'{DRAWIO_PATH} "{input_path}" -x -f svg -p {page} -o "{output_path}"'

""をつけない場合、以下の例ではsample2-page 1.svgではなくsample2-pageというファイルが生成されてしまいます。

コマンド
"C:\Program Files\draw.io\draw.io.exe drawio/sample2.drawio -x -f svg -p 0 -o image/sample2-page 1.svg

参考

drawio-cli
draw.io をコマンドラインで実行して、画像ファイルをエクスポートする
draw.ioの全てのタブを一括で画像出力する

更新履歴

  • 2023/12/05
    • 機能変更
      • 入力と出力のフォルダを分離するように変更
      • エラー処理を追加
    • バグ修正
      • drawioファイル内に1ページしかない場合にエラーになる問題を修正
    • その他
      • 実行環境を更新
      • コード全体を整理
9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5