13

I have installed on my PC draw.io app. I want to export all tabs with drawings to seperate files. The only options I have found is:

"c:\Program Files\draw.io\draw.io.exe" --crop -x -f jpg c:\Users\user-name\Documents\_xxx_\my-file.drawio

Help for draw.io

Usage: draw.io [options] [input file/folder]

Options:
(...)
  -x, --export                       export the input file/folder based on the
                                     given options
  -r, --recursive                    for a folder input, recursively convert
                                     all files in sub-folders also
  -o, --output <output file/folder>  specify the output file/folder. If
                                     omitted, the input file name is used for
                                     output with the specified format as
                                     extension
  -f, --format <format>              if output file name extension is
                                     specified, this option is ignored (file
                                     type is determined from output extension,
                                     possible export formats are pdf, png, jpg,
                                     svg, vsdx, and xml) (default: "pdf")
                                     (default: 0)
  -a, --all-pages                    export all pages (for PDF format only)
  -p, --page-index <pageIndex>       selects a specific page, if not specified
                                     and the format is an image, the first page
                                     is selected
  -g, --page-range <from>..<to>      selects a page range (for PDF format only)
(...)

is not supporting. I can use one of this:

  -p, --page-index <pageIndex>       selects a specific page, if not specified
                                     and the format is an image, the first page
                                     is selected
  -g, --page-range <from>..<to>      selects a page range (for PDF format only)

but how to get page-range or number of pages to select index?

Leszek
  • 451
  • 5
  • 19

6 Answers6

13

There is no easy way to find the number of pages out of the box with Draw.io's CLI options.

One solution would be export the diagram as XML.

draw.io --export --format xml --uncompressed test-me.drawio

And then count how many diagram elements there are. It should equal the number of pages (I briefly tested this but I'm not 100% sure if diagram element only appears once per page).

grep -o "<diagram" "test-me.xml" | wc -l

Here is an example of putting it all together in a bash script (I tried this on MacOS 10.15)

#!/bin/bash
file=test-me # File name excluding extension

# Export diagram to plain XML
draw.io --export --format xml --uncompressed "$file.drawio"

# Count how many pages based on <diagram element
count=$(grep -o "<diagram" "$file.xml" | wc -l)

# Export each page as an PNG
# Page index is zero based
for ((i = 0 ; i <= $count-1; i++)); do
  draw.io --export --page-index $i --output "$file-$i.png" "$file.drawio"
done

Eddie Groves
  • 33,851
  • 14
  • 47
  • 48
2

OP did ask the question with reference to the Windows version, so here's a PowerShell solution inspired by eddiegroves

$DIR_DRAWIO = "."

$DrawIoFiles = Get-ChildItem $DIR_DRAWIO *.drawio -File

foreach ($file in $DrawIoFiles) {
    
    "File: '$($file.FullName)'"
    
    $xml_file = "$($file.DirectoryName)/$($file.BaseName).xml"

    if ((Test-Path $xml_file)) {
        
        Remove-Item -Path $xml_file -Force
    }
    
    # export to XML
    & "C:/Program Files/draw.io/draw.io.exe" '--export' '--format' 'xml' $file.FullName

    # wait for XML file creation
    while ($true) {
        if (-not (Test-Path $xml_file)) {
            Start-Sleep -Milliseconds 200
        }
        else {
            break
        }
    }
    # load to XML Document (cast text array to object)
    $drawio_xml = [xml](Get-Content $xml_file)

    # for each page export png
    for ($i = 0; $i -lt $drawio_xml.mxfile.pages; $i++) {
        
        $file_out = "$($file.DirectoryName)/$($file.BaseName)$($i + 1).png"

        & "C:/Program Files/draw.io/draw.io.exe" '--export' '--border' '10' '--page-index' $i '--output' $file_out $file.FullName
    }

    # wait for last file PNG image file
    while ($true) {
        if (-not (Test-Path "$($file.DirectoryName)/$($file.BaseName)$($drawio_xml.mxfile.pages).png")) {
            Start-Sleep -Milliseconds 200
        }
        else {
            break
        }
    }
    # remove/delete XML file
    if ((Test-Path $xml_file)) {
        
        Remove-Item -Path $xml_file -Force
    }

    # export 'vsdx' & 'pdf'
    & "C:/Program Files/draw.io/draw.io.exe" '--export' '--format' 'vsdx' $file.FullName
    Start-Sleep -Milliseconds 1000
    & "C:/Program Files/draw.io/draw.io.exe" '--export' '--format' 'pdf' $file.FullName
}
Pete Thom
  • 21
  • 2
0

Based on @eddie-groves, here's script that will export all diagrams from draw.io file using sanitized diagram names. You can probably turn it into script that will accept all diagram_file_name, diagram_file_path, png_target_path as parameters.

Tested on Debian 11, draw.io 20.8

#!/bin/bash
# Export all drawio diagrams into PNG files. PNG files will have "sanitized" diagram names

export diagram_file_name=your_diagram_file_name # No extension
export diagram_file_path=./diagrams
export png_target_path=./diagrams/png

# Get diagram info. No need for --uncompressed : care only about <diagram name="..." ...> part.
drawio --export --format xml --output $diagram_file_path/$diagram_file_name.xml --page-index 0 $diagram_file_path/$diagram_file_name.drawio

# grep -Eo "name=\"[^\"]*": get name="... tokens/matches from xml
# cut -c7-: get diagram name (everything but starting 'name="'')
# sed -e 's/[^a-zA-Z0-9_]/_/: replace all possible unsafe charactecter for file names with underscore (_) 
# tr '[:upper:]' '[:lower:]': make all lower case
# awk '{print NR,$1}': add sequence number (NR) to output to indicate index of diagram
# xargs -n2 sh -c: get 2 arguments (index and sanitized driagram name) and pass to shell command
# drawio --export...: export diagram at specified index (0-based) to PNG
cat $diagram_file_path/$diagram_file_name.xml \
    | grep -Eo "name=\"[^\"]*" \
    | cut -c7- \
    | sed -e 's/[^a-zA-Z0-9_]/_/g' \
    | tr '[:upper:]' '[:lower:]' \
    | awk '{print NR,$1}' \
    | xargs -n2 sh -c \
    'drawio --export --format png --output $png_target_path/$1.png --page-index $(expr $0 - 1) $diagram_file_path/$diagram_file_name.drawio'


rm $diagram_file_path/$diagram_file_name.xml
arekam
  • 1
  • 1
0

Its worth noting that if you want to run draw.io from the command line, the scripts here all assume you have installed you one of the common releases.

These are available here: https://github.com/jgraph/drawio-desktop/releases

If you install draw.io through some other package command or as a Chrome Extension, it may not be as easy to script due to install location and permissions.

Ralph Willgoss
  • 11,750
  • 4
  • 64
  • 67
0

Answers from @Eddie Groves and @arekam are very good.

I used them as a start point for the following script:

alias draw="/Applications/draw.io.app/Contents/MacOS/draw.io"

# Export all pages of a diagram to PNG
# Based on: https://stackoverflow.com/q/65404843/2530295
draw-export-all-pages-to-png () {
    if [ "$#" -eq 0 ]; then
        echo 2>&1 "No input file entered"
        return 1
    fi
    if [[ ! "$1" == *.drawio ]]; then
        echo 2>&1 "Input file is not a .drawio file"
        return 1
    fi

    input="$1"
    output_dir="$(dirname "$1")/output"

    # Get the sanitized name of each page
    # Export the diagram to XML and parse the <diagram name="PAGE_NAME" .*> elements.
    tmp_xml=$(mktemp)
    draw --export --format xml --uncompressed "$input" --output "$tmp_xml" >/dev/null
    page_names=$(cat "$tmp_xml" | grep -E '<diagram( .*)?>' | grep -Eo 'name=\"[^\"]*' | cut -c7- | \
        tr "[:upper:]" "[:lower:]" | sed -e 's/[^a-z0-9_-]/_/g')

    # Export each page
    input_base_no_ext=$(basename "$input" .drawio)
    # Using `IFS=$'\n'` to convert a multiline string into an array.
    # See: https://unix.stackexchange.com/a/92190
    (){ local IFS=$'\n'; page_array=($=page_names); }
    mkdir -p "$output_dir"
    for i in {1..${#page_array[@]}}; do
        draw --export --format png --output "$output_dir/$input_base_no_ext-${page_array[$i]}.png" \
            --page-index $(( $i - 1 )) "$input"
    done
}

Notes:

  • It's a oh-my-zsh plugin, so code assumes MacOS and ZSH - not sure if will work in Bash without any modification.
  • Code exports the pages to an output directory. You may want to improve the code and make the output dir an optional parameter to the function.

I shared the code as a Github Gist as well: https://gist.github.com/rarylson/8160ddf9a2b6cc5343fab8261a063aaa.

0

Using drawio.exe you are able to drag and drop files onto this command script enter image description here

Edit for your preferred naming, numbering, format, etc. but note pages in drawio just like PDF start internally as number 0. in my case pages= was at position 19 but if yours are different you may need to add extra tests.

pages2images.cmd

@echo off
setlocal enabledelayedexpansion
for /F "usebackq tokens=19* delims= " %%f in ("%~n1.drawio") do set drawio_%%f
set "trim=%drawio_pages:~1% nul
set /a "count=%trim% - 1" 2>nul
if %count% neq -2 (
  echo Pages start from 0 and end at %count%
  for /l %%p in (0,1,%count%) do echo starting page %%p&&draw.io --crop -p %%p -o "%~dpn1-page-%%p.png" -x -f png "%~1" && echo\
) else (
echo exporting page 0 && draw.io --crop -p 0 -o "%~dpn1-page-0.png" -x -f png "%~1" && echo\
)

pause

Intentionally it shows progress and a pause to show any errors as with this file.

enter image description here

K J
  • 8,045
  • 3
  • 14
  • 36