Visual Inspection of Excel and PDF

WebページにリンクされたExcelファイルとPDFファイルをダウンロードし、あらかじめ保存しておいた過日分と比較して、差異があればそれを見やすい形式でレポートするツールを開発しました。名付けて　Visual Inspection of Excel and PDF 。これを紹介します。

GitHubに[プロジェクト](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF/)を公開しました。このプロジェクトはWeb UIテスト自動化ツール [Katalon Studio](https://www.katalon.com/katalon-studio/) のプロジェクトです。[Releases](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF/releases/) ページからプロジェクトのZIPをダウンロードすることができます。このプロジェクトを開発するのに Katalon Studio v8.6.0 の無償バージョンを使いました。バージョン依存性がほとんど無いのでどのバージョンでも動くはず。

## 開発した動機

数年前、わたしはメディア系の会社で仕事していた。そこでツール的なプログラムを作るよう依頼された。いわゆるWebスクレーピングのツールだった。スクレーピングの対象となるWebページは https://www.fsa.go.jp/policy/nisa2/about/tsumitate/target/index.html だった。このページは2023年4月現在もそのまま稼働している。

![target](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF/images/01_NISA_target_page.png)

このwebページがどういう趣旨・内容のものかはさておき、下記のような技術的なポイントに注目しよう。

1.  このページの中にExcelファイルへのリンク `<a href="…​">EXCEL</a>` がある。PDFファイルへのリンク `<a href="…​">PDF</a>` もある。リンクをクリックすれば .xlsx ファイルや　.pdf ファイルをダウンロードすることができる。

2.  ExcelとPDFファイルは発信者によって不定期に更新される。過去の実績によれば1ヶ月に一度ないしは2ヶ月に一度更新されるようだが、更新スケジュールが予め決められてアナウンスされることはない。

3.  このページは定型的であって、これらリンクが増えたり減ったりしない。ExcelファイルやPDFファイルのURL文字列は固定されている。タイミングによってURL文字列が変わることはない。

4.  このページの発信者はこのページが更新されたことをプッシュ通知する[RSSフィード](https://en.wikipedia.org/wiki/RSS)を提供しない。このページの内容に関心がある人は自分で頻繁にこのページを閲覧して更新の有無を探せばよかろうというわけだ。

5.  わたしが仕事していた会社はこのファイルにおおいに関心があった。ファイルが更新され次第やるべき仕事があった。だから何人かのスタッフがこのページを毎日目視確認するという仕事をしていた。もしファイルが更新されていたらファイルをダウンロードして自社システムに放り込んでデータ源として加工するためだ。いうまでもなく退屈な仕事だった。

6.  スタッフはこの仕事を嫌っていた。1ヶ月に一度しか起きないファイル更新に気づくために毎日webページを人の目でチェックするなんて。こんなクソどうでもいい仕事はシステムで自動化してほしいと皆望んでいた。

わたしは目的に叶うツールを開発した。それを説明します。

## 解決すべき問題

下記の問題を解決する必要があった。

1.  ツールは対象となるwebページを定期的かつ自動的に調べることができなければならない。例えば毎営業日に1日1回のペースで。

2.  ツールはExcelファイルやPDFファイルを目視して違う箇所を探し出すように調べることができなければならない。ファイルの日付やサイズが変わったという粒度では足りない。どこの文章がどう書き替えられたかがわからなければならない。だから

    -   直近バージョンのPDFファイルとExcelファイルをダウンロードして、過去にダウンロードしておいた古いバージョンのファイルと比較して、どこが書きかえられているかを発見できなければならない

    -   人間が見てわかる形式のレポートを編集して出力しなければならない。プログラマではない担当者がファイルの内容の差異を迷わず見つけられるように

    -   いまダウンロードしたPDFファイルとExcelファイルをどこか別の場所に退避しておかなければならない。比較対象として後で参照できるように。

3.  もしもExcelファイルに何らかの更新があったら、ツールは何らかの二次的なアクションを駆動することができなければならない。例えばファイルをどこかのファイルサーバに転送してMessage Queueにメッセージを投げてバッチ処理を駆動するとか、あるいは担当者にEメールを投げて連絡するとか。

第1の問題（定期実行・自動運用）を実現するにはいろいろ手段が考えられる。Linuxの[cron](https://en.wikipedia.org/wiki/Cron)とか、Windowsの[Task Scheduler](https://docs.microsoft.com/en-us/windows/win32/taskschd/about-the-task-scheduler)とか。あるいは[Jenkins](https://www.jenkins.io/)のようなCIツールを使うとか。

第３の問題(二次的アクションを駆動)を解決するには何らかのプログラムを開発する必要があるのは明白だ。場合によりけりで、計画を立てて頑張るしかない。

ここでわたしは第２の問題に注力することにしよう。どうやってPDFファイルやExcelファイルを比較しようか？私は[Visual Inspection in Katalon Studio](https://forum.katalon.com/t/visual-inspection-in-katalon-studio-reborn/57440)というプロジェクトを開発した。そのプロジェクトではPNG画像ファイル２つをピクセル単位で比較することができた。またテキストファイル２つをdiffして差分を取ることができた。テキストでありさえすればシンタックスはどうでもよくて、HTML, XML, JSON, CSV, CSS, JSなどなんでもアリだ。 **しかしながら `.xlsx` と `.pdf` はバイナリファイルだ。わたしのツールはバイナリファイルを直に比較するこができない。**

## 解決方法

わたしは [materialstore-mapper](https://github.com/kazurayam/materialstore-mapper) というJavaライブラリを自作した。これは同じく自作の [materialstore](https://github.com/kazurayam/materialstore) ライブラリを補完する。 `materialstore-mapper`ライブラリを使ってExcel `.xlsx` ファイルを`.csv`ファイルに形式変換することができる。またPDF `.pdf` ファイルをPNG画像ファイルに変換することができる。CSVとPNGに変換してしまえば、あとは`materialstore`ライブラリで差分比較とレポーティングをすればいい。

この[VisuakInspectionOfExcelAndPDF](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF) プロジェクトで、webページからExcelとPDFをダウンロードし、過日分と比較して、差異をレポートする仕事をこなすコードを例示する。

## デモ

下記のことを前提します。

1. あなたがKatalon Studio (無償版でOK)をインストール済みであること

1.  VisualInspectionOfExcelAndPDFプロジェクトのZIPファイルを[Releases](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF/releases)ページからダウンロードし、解凍すること

2.  自分のPCにJava8以上をインストールしていること

3.  ビルドツール [Gradle](https://gradle.org/) をインストールしていること

もしもあなたがGradleをまだ持っていないならこちらの [ガイド](https://forum.katalon.com/t/automated-visual-inspection/81966#setting-up-gradle-build-tool-22)を参照のこと

### デモを動かしてみる

#### 外部からjarをダウンロードして配置する

コマンドラインを開き、プロジェクトのディレクトリにcdして、下記の操作をします

    $ cd VisualInspectionOfExcelAndPDF
    $ gradle drivers

    $ gradle copyKatalonDependencies

これを実行するとKatalonプロジェクトのルートディレクトリの直下の `Drivers` フォルダの中にたくさんのjarファイルが配備されます。このデモを実行するのに必要なjarが含まれています（全部必要というわけではないが、選別する方が難しい）。

    $ ls Drivers
    AUTOIMPORTED_ExecutionProfilesLoader-1.2.1.jar          katalon_generated_jackson-dataformat-cbor-2.6.7.jar
    AUTOIMPORTED_ashot-1.5.4.jar                            katalon_generated_java-diff-utils-4.11.jar
    AUTOIMPORTED_commons-csv-1.9.0.jar                      katalon_generated_javassist-3.18.2-GA.jar
    AUTOIMPORTED_freemarker-2.3.31.jar                      katalon_generated_javax.activation-api-1.2.0.jar
    AUTOIMPORTED_inspectus-0.9.2.jar                        katalon_generated_jaxb-api-2.3.1.jar
    AUTOIMPORTED_java-diff-utils-4.11.jar                   katalon_generated_jcl-over-slf4j-1.7.5.jar
    AUTOIMPORTED_jsoup-1.14.3.jar                           katalon_generated_jdom2-2.0.6.1.jar
    AUTOIMPORTED_materialstore-0.16.2.jar                   katalon_generated_jmespath-java-1.11.232.jar
    katalon_generated_FontVerter-1.2.22.jar                 katalon_generated_jna-4.1.0.jar
    katalon_generated_annotations-2.0.1.jar                 katalon_generated_jna-platform-4.1.0.jar
    katalon_generated_ashot-1.5.4.jar                       katalon_generated_joda-time-2.8.1.jar
    katalon_generated_aws-java-sdk-core-1.11.232.jar        katalon_generated_jsoup-1.14.3.jar
    katalon_generated_aws-java-sdk-kms-1.11.232.jar         katalon_generated_jsr305-1.3.9.jar
    katalon_generated_aws-java-sdk-s3-1.11.232.jar          katalon_generated_materialstore-0.16.2.jar
    katalon_generated_cglib-nodep-2.1_3.jar                 katalon_generated_materialstore-mapper-0.10.2.jar
    katalon_generated_commons-codec-1.10.jar                katalon_generated_pdf2dom-2.0.1.jar
    katalon_generated_commons-collections4-4.1.jar          katalon_generated_pdfbox-2.0.26.jar
    katalon_generated_commons-csv-1.9.0.jar                 katalon_generated_pdfbox-debugger-2.0.26.jar
    katalon_generated_commons-exec-1.3.jar                  katalon_generated_pdfbox-tools-2.0.26.jar
    katalon_generated_commons-io-2.11.0.jar                 katalon_generated_poi-3.17.jar
    katalon_generated_commons-lang3-3.4.jar                 katalon_generated_poi-ooxml-3.17.jar
    katalon_generated_commons-logging-1.2.jar               katalon_generated_poi-ooxml-schemas-3.17.jar
    katalon_generated_curvesapi-1.04.jar                    katalon_generated_reflections-0.9.9.jar
    katalon_generated_fontbox-2.0.26.jar                    katalon_generated_rome-1.18.0.jar
    katalon_generated_freemarker-2.3.31.jar                 katalon_generated_rome-utils-1.18.0.jar
    katalon_generated_gson-2.8.2.jar                        katalon_generated_s3fs-2.2.2.jar
    katalon_generated_guava-19.0.jar                        katalon_generated_selenium-api-2.53.0.jar
    katalon_generated_hamcrest-core-1.3.jar                 katalon_generated_selenium-remote-driver-2.53.0.jar
    katalon_generated_httpclient-4.5.2.jar                  katalon_generated_slf4j-api-1.7.32.jar
    katalon_generated_httpcore-4.4.4.jar                    katalon_generated_stax-api-1.0.1.jar
    katalon_generated_ion-java-1.0.2.jar                    katalon_generated_subprocessj-0.3.4.jar
    katalon_generated_jackson-annotations-2.6.0.jar         katalon_generated_tika-core-1.5.jar
    katalon_generated_jackson-core-2.6.7.jar                katalon_generated_xmlbeans-2.6.0.jar
    katalon_generated_jackson-databind-2.6.7.1.jar

すごくたくさんjarがあります。わたしが自作した "materialstore" と "materialstore-mapper" ライブラリが使うjarです。あなたがこれらを詳しく知る必要はあまりありません。

#### デモの下地となるデータを準備する

Katalon Studioを起動してください。VisualInspectionOfExcelAndPDFプロジェクトを開きましょう。

スクリプト[Test Cases/NISA/setupFixture](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF/blob/develop/Scripts/NISA/setupFixture/Script1683011128442.groovy)を実行しましょう。このスクリプトは完了するまでに2分間ぐらいかかります。

![setupFixture](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF/images/02_setupFixture.png)

このスクリプトが完了すると `store/NISA_Chronos_20220307_100608` というフォルダが新しく作られます。その中にたくさんのフォルダとファイルが作られます。.xlsx, .pdf, .csv そして .pngがあります。このファイルはあなたが２０２２年３月７日午前１０時06分に `Test Cases/NISA/main_Chrome` スクリプトを実行していたならこうなったはずという状態を復元するためのものです。

![store initialized](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF/images/03_store_initialized.png)

#### Test Case "NISA/main\_Chronos"　を実行する

さて以上で、中心的なスクリプトを実行する準備が整いました。下記のスクリプトをKatalon Studioで実行してください。

-   [Test Cases/NISA/main\_Chronos](https://github.com/kazurayam/VisualInspectionOfExcelAndPDF/blob/develop/Scripts/NISA/main_Chronos/Script1682593110094.groovy)

このスクリプトは完了するのに３分間ぐらいかかるでしょう。完了するとHTMLレポートが生成されます。

-   [`<projectDir>/store/NISA_Chronos/index.html`](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF-sample-project/store/index.html)

このURLをブラウザで開き、あちこち探ってみて下さい。CSVファイルのdiffやPNGファイルの差分の実例をみることができます。

![diff CSV](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF/images/04_diff_csv.png)

![diff PNG](https://kazurayam.github.io/VisualInspectionOfExcelAndPDF/images/05_diff_png.png)

過去データと直近データの間に差異があればその量をツールが出力する。差異量が一定の閾値を超えたらかくかくしかじかの二次的処理を起動するようなシステムを構築することが可能。

実用性ありと思うが、いかがでしょうか。