JavaでPDFの表データをテキスト、CSV、およびExcelファイルに抽出する方法

PDFに埋め込まれた表データを正確に抽出し、テキスト、CSVファイル、またはExcelワークシートなど、より分析しやすく操作可能な形式にシームレスに変換することは、重要なドキュメント処理のスキルです。Javaを使用して、このプロセスを簡単に実現できます。本記事では、**Javaを使ってPDF文書から表データを抽出**し、**テキストファイル、CSVファイル、Excelワークシートに書き込む**方法をご紹介します。

- **[JavaでPDFの表をテキストファイルに抽出](#javaでpdfの表をテキストファイルに抽出)**
- **[JavaでPDFの表をCSVファイルに抽出](#javaでpdfの表をcsvファイルに抽出)**
- **[JavaでPDFの表をExcelファイルに抽出](#javaでpdfの表をexcelファイルに抽出)**

この記事で使用する方法は、主に無料の[Free Spire.PDF for Java](https://jp.e-iceblue.com/introduce/free-spire-pdf-for-java.html)ライブラリを必要とします。ダウンロードしてインポートするか、Mavenを介してインポートすることができます：

```xml
<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.pdf.free</artifactId>
    <version>9.13.0</version>
</dependency>
```

PDFの表を抽出するには、ライブラリ内の`PdfTableExtractor`クラスを使用します。読み込んだPDFファイルに対して`PdfTableExtractor`オブジェクトを作成し、`PdfTableExtractor.extractTable()`メソッドを使用して、指定したページ内のすべての表を抽出します。最後に`PdfTable.getText()`メソッドで表のデータを取得できます。以下に一般的な操作手順を示します：

- `PdfDocument`オブジェクトを作成し、`PdfDocument.loadFromFile()`メソッドでPDF文書を読み込む。
- 読み込んだPDF文書から`PdfTableExtractor`オブジェクトを作成する。
- `PdfTableExtractor.extractTable()`メソッドを使用して、各ページの表を抽出する。
- `PdfTable.getText()`メソッドでPDF表のセルデータを取得する。

この方法で表データを取得した後、それをテキストファイルに書き込んだり、CSVやExcelファイルとして保存したりすることが可能です。

## JavaでPDFの表をテキストファイルに抽出
`PdfTableExtractor.extractTable()`メソッドで表を抽出し、`PdfTable.getText()`メソッドでセルデータを取得した後、文字列を構築してテキストファイルに書き込むことができます。以下に詳細な手順を示します：

1. 必要なモジュールをインポートする。
2. `PdfDocument`オブジェクトを作成し、`PdfDocument.loadFromFile()`メソッドでPDF文書を読み込む。
3. 読み込んだPDF文書から`PdfTableExtractor`オブジェクトを作成する。
4. 各ページをループし、`PdfTableExtractor.extractTable()`メソッドで表を抽出する。
5. 抽出した表ごとに`StringBuilder`オブジェクトを作成する。
6. 表の行と列をループし、`PdfTable.getText()`メソッドでセルのデータを取得し、改行を削除する。セルデータを`StringBuilder`オブジェクトに追加する。
7. `StringBuilder`オブジェクトをテキストファイルに書き込む。
8. リソースを解放する。

**コード例**
```java
import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;

import java.io.FileWriter;
import java.io.IOException;

public class extractPDFToText {
    public static void main(String[] args) throws IOException {
        // PdfDocumentオブジェクトを作成
        PdfDocument pdf = new PdfDocument();
        // PDFドキュメントをロード
        pdf.loadFromFile("Sample.pdf");

        // PdfTableExtractorオブジェクトを作成
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);

        // 各ページからテーブルを抽出
        for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {
            PdfTable[] tables = extractor.extractTable(pageIndex);
            // テーブルがnullでない場合に繰り返し処理
            if (tables != null) {
                for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {
                    PdfTable table = tables[tableIndex];
                    // StringBuilderオブジェクトを作成
                    StringBuilder tableText = new StringBuilder();
                    // 行と列を繰り返し処理
                    for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
                        for (int colIndex = 0; colIndex < table.getColumnCount(); colIndex++) {
                            // セルのテキストを取得し、改行を削除
                            String cellText = table.getText(rowIndex, colIndex);
                            cellText = cellText.replaceAll("\\r|\\n", "");
                            if (colIndex < table.getColumnCount() - 1) {
                                tableText.append(cellText).append("\t");
                            } else {
                                tableText.append(cellText).append("\n");
                            }
                        }
                    }
                    System.out.println(tableText);
                    // テーブルをテキストファイルに書き込む
                    try (FileWriter writer = new FileWriter("output/Tables/Page" + (pageIndex+1) + "-Table" + (tableIndex+1) + ".txt")) {
                        writer.write(tableText.toString());
                    }
                }
            }
        }
    }
}
```

抽出結果
![JavaでPDFの表をテキストファイルに抽出](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/61a6d09d-a2f0-4bb4-e14b-c1cf5e7f1259.png)

## JavaでPDFの表をCSVファイルに抽出
同様の手法で表データを抽出し、opencsvなどのモジュールを組み合わせて、抽出したデータをCSVファイルに書き込むことができます。また、以下のExcelファイルへの書き込み方法を使って、最終的にCSV形式で保存することも可能です。

opencsv：
```xml
<dependency>
  <groupId>com.opencsv</groupId>
  <artifactId>opencsv</artifactId>
  <version>5.9</version>
</dependency>
```

以下はopencsvを使用してPDF表データを抽出し、CSVファイルに書き込む手順です：

1. 必要なモジュールをインポートする。
2. `PdfDocument`オブジェクトを作成し、`PdfDocument.loadFromFile()`メソッドでPDF文書を読み込む。
3. 読み込んだPDF文書から`PdfTableExtractor`オブジェクトを作成する。
4. 各ページをループし、`PdfTableExtractor.extractTable()`メソッドで表を抽出する。
5. 抽出した表をループし、CSVファイル名を作成する。
6. `CSVWriter`オブジェクトを作成し、表の行と列をループし、`PdfTable.getText()`メソッドでセルデータを取得し、改行を削除する。抽出した表データを文字列リストに構築し、CSVデータ行として書き込む。
7. リソースを解放する。

**コード例**
```java
import com.opencsv.CSVWriter;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;

import java.io.FileWriter;
import java.io.IOException;

public class extractPDFTableToCSV {
    public static void main(String[] args) throws IOException {
        // PdfDocumentオブジェクトを作成
        PdfDocument pdf = new PdfDocument();
        // PDFドキュメントをロード
        pdf.loadFromFile("Sample.pdf");

        // PdfTableExtractorオブジェクトを作成
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);

        // 各ページからテーブルを抽出
        for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {
            PdfTable[] tables = extractor.extractTable(pageIndex);
            // テーブルがnullでない場合に繰り返し処理
            if (tables != null) {
                for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {
                    PdfTable table = tables[tableIndex];
                    // CSVファイル名を作成
                    String csvFileName = "output/Tables/Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1) + ".csv";
                    // CSVWriterオブジェクトを作成
                    try (CSVWriter writer = new CSVWriter(new FileWriter(csvFileName))) {
                        // 行と列を繰り返し処理
                        for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
                            String[] row = new String[table.getColumnCount()];
                            for (int colIndex = 0; colIndex < table.getColumnCount(); colIndex++) {
                                // セルのテキストを取得し、改行を削除
                                String cellText = table.getText(rowIndex, colIndex).replaceAll("\\r?\\n", "");
                                row[colIndex] = cellText;
                            }
                            // CSVファイルに行を書き込む
                            writer.writeNext(row);
                        }
                    }
                }
            }
        }
        pdf.close();
    }
}
```

抽出結果
![JavaでPDFの表をCSVファイルに抽出](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/9485a46b-dab9-bfe8-8986-6b7e80af6250.png)

## JavaでPDFの表をExcelファイルに抽出
PDF表データをExcelシートに保存するには、[Free Spire.XLS for Java](https://jp.e-iceblue.com/introduce/free-spire-xls-for-java.html)を使用します。PDF文書から抽出した表のセルデータを`Worksheet.getRange().setText()`メソッドでExcelワークシートの対応するセルに書き込み、保存することでPDF表データをExcelファイルに変換できます。また、保存時にフォーマットをCSVに設定することで、PDF表データをCSVファイルとして保存することもできます。

Free Spire.XLS for Java：
```xml
<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.xls.free</artifactId>
    <version>5.3.0</version>
</dependency>
```

以下は詳細な手順です：

1. 必要なモジュールをインポートする。
2. `PdfDocument`オブジェクトを作成し、`PdfDocument.loadFromFile()`メソッドでPDF文書を読み込む。
3. `Workbook`オブジェクトを作成し、`Workbook.getWorksheets().clear()`メソッドでデフォルトのワークシートをクリアする。
4. 読み込んだPDF文書から`PdfTableExtractor`オブジェクトを作成する。
5. 各ページをループし、`PdfTableExtractor.extractTable()`メソッドで表を抽出する。
6. 抽出した表ごとに、`Workbook.getWorksheets().add()`メソッドで指定した名前のワークシートを作成する。
7. 表の行と列をループし、`PdfTable.getText()`メソッドでセルデータを取得し、改行を削除する。その後、`Worksheet.getRange().setText()`メソッドでセルデータを対応するセルに書き込む。
8. ワークシートのセルの形式を設定する。
9. `Worksheet.autoFitRow()`と`Worksheet.autoFitColumn()`メソッドで行の高さと列の幅を自動調整する。
10. `Worksheet.saveToFile()`メソッドを使ってCSVファイルとして保存できる。
11. `Workbook.saveToFile()`メソッドを使ってExcelファイルとして保存する。
12. リソースを解放する。

**コード例**
```java
import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import com.spire.xls.*;

public class extractPDFTableToExcel {
    public static void main(String[] args) {
        // PdfDocumentオブジェクトを作成
        PdfDocument pdf = new PdfDocument();
        // PDFドキュメントをロード
        pdf.loadFromFile("Sample.pdf");

        // Workbookオブジェクトを作成
        Workbook workbook = new Workbook();
        workbook.getWorksheets().clear();

        // PdfTableExtractorオブジェクトを作成
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);

        // 各ページからテーブルを抽出
        for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {
            PdfTable[] tables = extractor.extractTable(pageIndex);
            // テーブルがnullでない場合に繰り返し処理
            if (tables != null) {
                for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {
                    // ワークブックにワークシートを追加
                    Worksheet sheet = workbook.getWorksheets().add("Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1));
                    // テーブル内の行と列を繰り返し処理
                    for (int rowIndex = 0; rowIndex < tables[tableIndex].getRowCount(); rowIndex++) {
                        for (int colIndex = 0; colIndex < tables[tableIndex].getColumnCount(); colIndex++) {
                            // セルのテキストを取得し、改行を削除
                            String cellText = tables[tableIndex].getText(rowIndex, colIndex).replaceAll("\\r|\\n", "");
                            // ワークシートにセルのテキストを書き込む
                            sheet.getCellRange(rowIndex+1, colIndex+1).setText(cellText);
                        }
                    }
                    // セルのスタイルを設定
                    CellRange[] rows = sheet.getRows();
                    rows[0].getStyle().getFont().setFontName("HarmonyOS Sans SC");
                    rows[0].getStyle().getFont().setSize(12);
                    rows[0].getStyle().getFont().isBold(true);
                    rows[0].getStyle().setHorizontalAlignment(HorizontalAlignType.Center);
                    for (int i = 1; i < rows.length; i++) {
                        rows[i].getStyle().getFont().setFontName("HarmonyOS Sans SC");
                        rows[i].getStyle().getFont().setSize(12);
                        rows[i].getStyle().setHorizontalAlignment(HorizontalAlignType.Left);
                    }
                    // 行と列を自動調整
                    for (int i = 0; i < rows.length; i++) {
                        sheet.autoFitRow(i+1);
                    }
                    for (int i = 0; i < sheet.getColumns().length; i++) {
                        sheet.autoFitColumn(i+1);
                    }
                    sheet.saveToFile("output/Tables/PDFTableToCSV-Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1) + ".csv", ",");
                }
            }
        }

        // ワークブックを保存
        workbook.saveToFile("output/PDFTableToExcel.xlsx");
        pdf.close();
        workbook.dispose();
    }
}
```

抽出結果
![JavaでPDFの表をExcelファイルに抽出](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/97d1467d-567e-31a7-adac-b558ab6027d0.png)

この記事では、Javaを使用してPDF表データをテキスト、CSV、およびExcelファイルに書き込む方法を紹介しました。

さらに詳しいPDF文書操作のテクニックは、[Spire.PDF for Javaのチュートリアル](https://www.e-iceblue.com/Tutorials/JAVA/Spire.PDF-for-JAVA/Program-Guide/Spire.PDF-Program-Guide-Content-for-JAVA.html)をご覧ください。