◇はじめに
本記事はExcel業務をDX化したい。あなたならどうする? by MESCIUS Advent Calendar 2025
2日目の記事です。
今回は、【Excel業務をDX化したい。】というテーマに沿って、神Excelをデジタル化するというネタを紹介します。
◇背景
神Excelとは?
神Excelという言葉を聞いたことはありますか?
正式な定義は多分ありませんが、
- セルの縦横比が方眼紙状
- 入力したものをそのまま印刷することを想定したレイアウト
- そのまま印刷して手書きで記入することも想定されている
といった感じのExcelファイルで、主に官公庁の申請書等で使われることが多い印象です。
別サービスとの連携が難しい
神Excelはそのレイアウトの関係でデータの抽出が難しく、他のクラウドサービスとの連携が難しいことが多いです。
そのため、1項目ごとに手作業で転記するといった作業が発生することがあり、手間がかかります。
何とか別サービスと連携させたい
後述しますが、本来の対策は神Excelを使わないようにすることです。
ただし、それだと記事にならないので実際には自社の判断だけではどうにもならないケース(フォーマット自体を決めているのは、別会社のパターン)も多く、改善が難しい場面もあります。
そういった場合、Excelのフォーマットはそのままにしつつ、入力データを別システムに別途連携させる方法が考えられます。
神Excelを使いつつ、その入力データを自社内のシステムに連携させたい場合、
- システムに入力したデータから神Excelに転記する
- 神Excelに入力したデータをシステムに転記する
のどちらかの方法が考えられますが、
今回は、2番目の方法をn8nを使って実現した事例を紹介します。
◇環境等
- Microsoft Excel
- Microsoft365 Business Standard
- デスクトップ版
- n8n
- ホストOS
- Proxmox VE 8.3
- VM
- Ubuntu 24.04.3 LTS
- Docker version 28.1.1+1
- Docker Compose version v2.33.1
- n8n: 1.118.2
- ホストOS
- kintone
- kintone開発者ライセンス
◇実装手順
n8nのセットアップ
n8nとは
今回、Excelを処理するのに、n8nというサービスを使用しています。
n8nはいわゆるiPaaS(Integration Platform as a Service)に分類されるサービスの1つで、最近ではAIワークフローと呼ばれたりもしてます。
これらのサービスを使うことで、様々なクラウドサービスを連携することができます。
n8nの特徴の1つとして、セルフホスト型での利用が可能な点があります(Community版では無料で利用可能)。
そして、このセルフホスト型n8nはオンプレデータに対するフローの実行も可能なため、オンプレミス上のExcelファイルの処理も行えると考え、本ツールを採用しました。
n8nのインストール手順
セルフホスト型のn8nについては、ローカルのPC上にインストールする形としました。
今回はDockerを使ってn8nをインストールしましたが、Docker環境までの構築手順は本記事では割愛します。
以前、別記事にてProxmox VEのインストールからVMの構築までをまとめていますので、必要に応じてそちらをご覧ください。
(Ubuntuインストール時にインストールするパッケージでDockerを選択することでDockerのインストールが可能です)
基本的には、公式ドキュメントやGitHubの手順に従いつつ、生成AIにもサポートしてもらいながら以下のcompose.yamlを作成しました。
services:
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: ${DB_POSTGRESDB_USER}
POSTGRES_PASSWORD: ${DB_POSTGRESDB_PASSWORD}
POSTGRES_DB: ${DB_POSTGRESDB_DATABASE}
TZ: ${TZ}
volumes:
- ./postgres:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
depends_on:
- db
ports:
- "5678:5678"
environment:
TZ: ${TZ}
N8N_SECURE_COOKIE: ${N8N_SECURE_COOKIE}
N8N_PROTOCOL: http
# 認証
N8N_BASIC_AUTH_ACTIVE: ${N8N_BASIC_AUTH_ACTIVE}
N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER}
N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
# DB 設定
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: db
DB_POSTGRESDB_DATABASE: ${DB_POSTGRESDB_DATABASE}
DB_POSTGRESDB_USER: ${DB_POSTGRESDB_USER}
DB_POSTGRESDB_PASSWORD: ${DB_POSTGRESDB_PASSWORD}
DB_POSTGRESDB_PORT: 5432
volumes:
- ./.n8n:/home/node/.n8n
- ./local-files:/files
compose.yaml内に記載されている変数(${DB_POSTGRESDB_USER}など)は同フォルダ内に.envファイルを作成し、そのファイル内で別途定義しています。
ファイル作成後、以下のコマンドを実行してn8nを起動します。
docker compose up -d
しばらくすると、n8nが起動するので、今回使用しているVMのIPアドレスにアクセスします。
http://{{vm_ip_address}}:5678/
n8nの画面が表示されれば、とりあえずOKです。
具体的なn8nでのフロー作成については、別途後述します。
Excelファイルの準備
次に、n8nで処理するためのExcelファイルを準備します。
実際に使われているExcelを使ってもよいのですが、今回はせっかくなので、生成AIを使ってそれっぽいフォーマットを作成してもらい、一部手直ししています。
作ったExcelファイルは以下のような感じです。
n8nでのフロー作成
次は、実際に作成したExcelファイルをn8nで処理するためのフローを作成します。
実際に今回作成したフローの全体像を以下に示します。
それぞれのセクションを順に説明します。
Excelファイルを検出
このセクションでは、指定したフォルダ内にあるExcelファイルが置かれたことを検出して、フローが開始されます。
Local File Triggerノードにて、監視するフォルダを指定しています。
今回は、/files/inbound/excelフォルダを監視するように設定しています。
トリガが発生する条件として、ファイル追加や更新、フォルダ追加などを指定できますが、今回はファイルの追加時のみを指定しています。
Read/Write Files from Diskノードにて、追加されたファイルを読み込みます。
なお、この時点ではexcelファイルかのチェックは行っていないので、置かれたファイルの種類に限らず、読み込みます。
※当初、このノード内で拡張子チェックを行おうとしましたが、うまくいかなかったため、次のFilterノードでチェックしています。
Filterノードにて、読み込んだファイルの拡張子が.xlsxであるかをチェックしています。
.xlsx以外のファイルが置かれた場合は、ここでフローが終了します。
Excelファイルからデータを抽出
このセクションでは、読み込んだxlsxファイルから各項目のデータを抽出します。
最初に、Extract From Fileノードを並列に並べていますが、これは各行ごとにデータを抽出するための処理になります。
本来のExcelファイルでは見出し行の下にデータ行が連続して並んでいることを想定していますが、今回は申請書様式の特殊な構成のため、各項目行ごとにデータを抽出する必要があります。
氏名、生年月日、性別の項目が含まれている6-7行目の例を説明すると、RangeのOptionsでA6:AJ7を指定しています。
これは、元のExcelファイルで、項目名と入力欄が含まれている範囲を指定しています。
Sheet Name欄は今回のExcelファイルのシート名をそのまま記載します。
並列化されているフローの中で、一部Edit Fields (Set)ノードを配置しています。
Excelの日付データは1900年1月1日(又は1904年1月1日)を起点としたシリアル値で保存されるため、そのままではn8nで扱いにくいため、ここで変換を行っています。
Excelの日付システムについてはこちらのMicrosoft サポートサイトにも記載があります。
並列化されたフローは、MergeノードとAggregateノードで1つにまとめています。
Mergeノードは前段のノードすべての完了を待つ効果もあります。
Aggregateノードで1つのdataオブジェクトにまとめています。
データをクラウドサービスに登録
このセクションで、先ほどまでに抽出したデータをクラウドサービスに登録します。
そのために、まずはデータを保存するクラウドサービスを用意する必要があります。
今回は、例としてkintoneを使用しています。
kintoneは、サイボウズ社が提供している業務アプリ作成用クラウドサービスです。
今回はkintone開発者ライセンスを使って、アプリを作成しています。
アプリの作成手順については、公式チュートリアルがあるので、今回は詳細は割愛します。
今回作成したアプリの画面は以下のような感じです。
※縦長になってしまったので、スクリーンショットを分割しています
各項目のフィールドは以下のように設定しています。
| フィールド名 | フィールドコード | フィールドタイプ |
|---|---|---|
| 氏名(漢字) | name_kanji | 文字列(1行) |
| 氏名(フリガナ) | name_kana | 文字列(1行) |
| 生年月日 | birthdate | 日付 |
| 性別 | gender | ドロップダウン |
| 住所 | address | 文字列(1行) |
| 電話番号(携帯可) | phone | リンク |
| メールアドレス | リンク | |
| 申請の種類 | application_type | ドロップダウン |
| 提出先(部署名) | department | 文字列(1行) |
| 申請理由(できるだけ具体的に) | application_reason | 文字列(複数行) |
| 処理期限 | doc_date | 日付 |
| 関連番号(例:住民票コード等) | reference_number | 文字列(1行) |
| 添付書類 | attachment | ドロップダウン |
| その他資料詳細 | attachment_detail | 文字列(1行) |
| 連絡希望手段 | contact_method | ドロップダウン |
| 連絡可能時間帯(例:9:00-18:00) | contact_time_range | 文字列(1行) |
| 署名 | signature | 文字列(1行) |
| 署名日 | sign_date | 日付 |
| 担当者記入欄(受付番号など) | staff_receipt_memo | 文字列(1行) |
フォームの配置が完了したら、最後にREST APIトークンを発行します。
kintoneのレコード登録手順については、公式ドキュメントがあるので、こちらを参考にしながら、n8nのフローを作成します。
Edit Fields (Set)ノードでkintoneにデータを登録するために必要な各種パラメータを変数にセットしています。
ここで、セットしているのは、base_urlとappIdの2つで認証に必要なX-Cybozu-API-Tokenはここでは設定不要です。
この2つのパラメータはkintoneのドキュメントを参考にしながら、先ほど作成したアプリのIDと自分のkintoneドメインのURLを設定します。
次に、HTTP Requestノードで実際にkintoneにデータを登録しています。
ノード設定の上部で認証関係のパラメータを設定します。
Authentication、Generic Auth Type欄はそれぞれ下の画像のように設定した後、Header Auth項目右側🖊アイコンを選択します。
Header Authの詳細設定画面が表示されたら、Name欄にX-Cybozu-API-Tokenを入力し、Value欄に先ほど発行したAPIトークンを入力します。
この状態でSaveを実行すると、Credentialが保存されますので、次回以降は今回の設定を再利用できます。
Body Parameters欄では、kintoneのレコード登録APIの仕様に従って、登録するデータを順次設定します。
基本的に、Name欄はkintoneアプリのフィールドコードに合わせて入力し、Value欄にn8n内で抽出したデータをドラッグして設定します。
ここまで設定が完了したら、フローは完成です。
テスト
最後に作成したフローをテスト実行します。
先ほどのフローの最初のノードの左側にある"⚡"アイコンにマウスを合わせると表示されるExecute workflowをクリックします。
Local File Triggerノードが実行待ちの状態となるので、事前に設定したフォルダ内にExcelファイルを配置します。
ファイル配置後、フローが動き出し、以下の画像のように、画面右下にWorkflow executed successfullyと表示されれば成功です。
実際に今回テストで使ったExcelファイルがこちらです。
そして、kintone側に登録されたデータがこちらです。
データが正しく登録されていることが確認できます。
これでテスト実行が確認できたので、画面右上からフローをActiveに変更すればフローが常時実行されるようになります。
◇今回見送った内容
当初、実装する予定でしたが、解決策が時間内に見つからなかったため、見送ったものもあります。
kintoneのチェックリスト形式での登録
当初、Excel側で○×形式で項目を入力させ、○が入っている項目のみ抜き出してkintoneに登録することを検討していました。
しかし、ループ処理での抜き出しがうまくいかず、今回は見送っています。
空白セルがあった場合の処理
入力項目によってはブランクのままの項目も実際にはあるかと思います。
ただし、今回のフローではすべての入力欄に何かしらの値が入っていないとエラーが発生します。
現状のフローですと、セルが空白の場合、そのセルのデータは取り出さない設定となっており、後段でkintoneにデータを登録する際にそのセルのデータが存在しないため、エラーとなります。
空白セルも含めて項目を取り出すように設定を変えることはできるのですが、その設定に変えた場合、セル結合で隠れた部分のセルが全て空白として取り出されてしまいました。
後段でのデータの整形が難しかったため、このような対応なっています。
それぞれ、今後の課題としていつか改善できればと考えています。
◇おわりに
冒頭でも書きましたが、根本的な解決策は神Excelを使わないようにすることであり、今回の方法は暫定的な非推奨の対策となります。
ただし、どうしても既存のExcelフォーマットを使い続けなければならない場合、今回のようにn8nのようなセルフホスト型ワークフローを活用することで、作業を効率化できる方法もあることを知っていただければ幸いです。
この後もアドカレの記事が続きますので、ぜひお楽しみください。