【Java初心者】複数のWordファイルの表をまとめる

# オフィスではコピペによるデータのまとめが多すぎる

ビジネスの現場では、上司への説明用にワードファイルの「個表」を作ることが多い。

そして、それを後でまとめるために、複数の「個表」のワードから特定のセルの文字を抽出し、エクセルにまとめたりする。

オープンデータとして公開されているCSVやJSONばかりいじっていたので、「まずはデータを作り、差し込み印刷で個表にしたらいいのに」と思うが、ビジネスの現場では、資料は上司に提出したり、会議用の資料としてまとめたりするのに使われる。つまり、多くのWordファイルは、データの再利用は全く想定していない。

ただ、それをあとになって「エクセルで一覧を作って下さい」となると、一枚ずつWordで開いてデータをコピペせざるをえない。そういう要求は多いし、多くのビジネスマンがその作業に時間を使っていると思われる。

# 参考にしたサイト

マクロでやればいいのかもしれないけど、詳しくないので、Javaでできるか試してみる。

「word 表 セルから文字抽出 java」として検索すると、

[Word文書で表を作成または読み取る方法【Java】](https://qiita.com/iceblue/items/a2c03b0c802579cc13e6)という情報が見つかった。
これを参考にしながら書いていきます。素晴らしい情報をありがとうこざいました。

# 処理したいテストファイルを用意

処理したいWordは以下のような書式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660337/2109f1df-1879-be84-ab12-89f4f6168753.png)

このうち、「テーマ」や「概要」などを少し変えたWordファイルを doc ディレクトリに複数格納する。

# Javaで書いてみる

上記サイトのように、[Free Spire.Doc for Javaライブラリ](https://repo.e-iceblue.com/service/rest/repository/browse/maven-public/e-iceblue/spire.doc.free/5.2.0/)を使います。ダウンロードし、クラスパスに入れます。

```java
package doctabletest;

import com.spire.doc.Document;
import com.spire.doc.Section;
import com.spire.doc.TableCell;
import com.spire.doc.TableRow;
import com.spire.doc.collections.TableCollection;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.interfaces.ITable;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.StringJoiner;

public class Main {

    public static void main(String[] args) throws IOException {
        Document document = new Document();

        File dir = new File("docs");
        File[] files = dir.listFiles();
        StringJoiner sj = new StringJoiner(System.lineSeparator());
        sj.add("表\t行\t列\tファイル\t内容");
        
        for (File file : files) {

            document.loadFromFile(file.getAbsolutePath());

            Section section = document.getSections().get(0);

            TableCollection tables = section.getTables();

            Iterator iterator = tables.iterator();
            int n = 0;
            while (iterator.hasNext()) {
                n++;
                ITable table = (ITable) iterator.next();
                for (int i = 0; i < table.getRows().getCount(); i++) {
                    TableRow row = table.getRows().get(i);
                    for (int j = 0; j < row.getCells().getCount(); j++) {
                        TableCell cell = row.getCells().get(j);
                        StringBuilder sb = new StringBuilder();
                        for (int k = 0; k < cell.getParagraphs().getCount(); k++) {
                            Paragraph paragraph = cell.getParagraphs().get(k);
                            String text = paragraph.getText();
                            sb.append(text);
                        }
                        sj.add(
                                String.valueOf(n) + "\t"
                                + String.valueOf(i) + "\t"
                                + String.valueOf(j) + "\t"
                                + file.getName() + "\t"
                                + sb.toString());
                    }
                }
            }
        }
        Files.write(Path.of("表のデータ.txt"), sj.toString().getBytes());
    }
}
```

# 処理結果

表のデータ.txt というファイルを見ると

```
表	行	列	内容
1	0	0	提案3.docx	提案職員C
1	0	1	提案3.docx	承認部長A
2	0	0	提案3.docx	テーマ
2	0	1	提案3.docx	テーマABCDE-3
2	1	0	提案3.docx	概要
2	1	1	提案3.docx	概要3
2	1	2	提案3.docx	新規
2	2	0	提案3.docx	予算
2	2	1	提案3.docx	5万円
2	2	2	提案3.docx	期限 2024年10月
2	3	0	提案3.docx	メモ
2	3	1	提案3.docx	メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。メモ3。
1	0	0	提案1.docx	提案職員A
1	0	1	提案1.docx	承認部長A
2	0	0	提案1.docx	テーマ
2	0	1	提案1.docx	テーマABCDE-1
2	1	0	提案1.docx	概要
2	1	1	提案1.docx	概要1
2	1	2	提案1.docx	新規
2	2	0	提案1.docx	予算
2	2	1	提案1.docx	10万円
2	2	2	提案1.docx	期限 2024年12月
2	3	0	提案1.docx	メモ
2	3	1	提案1.docx	メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。メモ1。
1	0	0	提案2.docx	提案職員B
1	0	1	提案2.docx	承認部長A
2	0	0	提案2.docx	テーマ
2	0	1	提案2.docx	テーマABCDE-2
2	1	0	提案2.docx	概要
2	1	1	提案2.docx	概要2
2	1	2	提案2.docx	新規
2	2	0	提案2.docx	予算
2	2	1	提案2.docx	12万円
2	2	2	提案2.docx	期限 2024年11月
2	3	0	提案2.docx	メモ
2	3	1	提案2.docx	メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。メモ2。
```

こんな感じになります。

これをソートし、「2 0 1」という行だけを取り出すと、「テーマ」に書かれたテキストが並びます。その部分をエクセルにコピペするだけ。

すべてプログラムでやりたいとか、システム化したい場合は、Apache POI使えればいいけど。