PDF - テキストオブジェクト - Excelセル結合のワナ

## はじめに

Excel を PDF 化した場合、PDF 内のテキストオブジェクト（文字列オブジェクト）は、行単位のデータとして格納されます。
［A1セルの文字列 + B1セルの文字列 + ...］
［A2セルの文字列 + B2セルの文字列 + ...］
　：

このような基本動作を阻む「Excelセル結合のワナ」について記載しようと思います。

### 参考情報
下記情報を参考にさせて頂きました。

- [テキスト - PDFフォーマット](https://azelpg.gitlab.io/azsky2/note/prog/pdf/15_text.html)
- [簡単そうで簡単ではないPDFのテキスト抽出](https://www.antenna.co.jp/pdf/reference/text-extractor.html)

### 利用ツール

https://github.com/itext/i7j-rups/releases

iText7-RUPS-7.2.5.zip をダウンロード/解凍、Java Runtime を別途導入した後、itext-rups-7.2.5.jar を起動します。

### テスト環境

ここに記載した情報は、Windows 11 24H2 で確認しています。

## Excelセル結合のワナ

数年前、C# で PDF からの文字抽出ソフトを利用して、収集した PDF に対して文字抽出の確認時、期待する文字列が取得できないケースに遭遇しました。

```
本来の期待値
2025 年 1 月 25 日

実際の取得値
 年 月 日
[他データ 数行]
2025
1
25
```

PDF 内の情報から、Excel から「Microsoft Print To PDF」で PDF 化したものだと確認できました。

::: note
上記は itext/rups で確認できます。

![RUPS-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/5c853c07-f358-d39d-11ac-117a6b27c79d.png)
:::

原本 Excel が手元にありませんでしたが、対象 PDF を Excel で再現して、セル結合が起因とわかりました。

![Excel-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/c69b107e-5c13-9968-09a7-3f0cc3d98c6a.png)

Excel を PDF 化して、PDF からの文字抽出ソフトで文字抽出を行うと、下記結果が得られます。

```
見積作成日  年  月  日
見積有効期限  年  月  日
上記２行 E-F、H-I、K-L 列はセル結合
2025
1
25
2025
2
25
```

Adobe Acorbat で該当 PDF を表示して、コピペ選択をすると、セル結合を避けて選択されることも確認しました。

![AdobeReader.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/efbb8c59-2ded-359b-de97-21648c0c2f51.png)

## 確認調査

状況証拠を押さえましたが、確認調査として、PDF ストリームを見てみることにします。

### テキストオブジェクト

PDF に格納されているテキストオブジェクトは、ストリームで確認すると、`BT`～`ET` として展開されます。

```
BT
  テキストレンダリングモード Tr
  フォント情報 Tf
  テキスト空間変換行列 Tm
  テキスト Tj
ET
```

::: note
PDF 作成ソフトによって、異なる構造になる可能性があります。
:::

### セル結合なし

ストリーム確認を単純にしたいので、コンパクトな下記 Excel を用意します。

![Excel-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/310fce9e-2174-0f76-2425-bb002e12490b.png)

Excel から PDF出力して、PDF を itext/rups でストリーム確認してみます。

![RUPS-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/ecf505b2-5f21-e0c1-18d6-d3839d787400.png)

最初の　`BT`～`ET` が、Excel １行目に対応するテキストオブジェクトで、文字データは下記のようになります。
<0024> → A
<0025> → B
<0026> → C

続いて２個目のテキストオブジェクト（テキスト空間変換行列が異なり、同一テキストデータの Excel ２行目）が確認できます。

以上から、Excel を PDF 化した場合、基本的には、行単位のテキストオブジェクトが生成されることがわかりました。

::: note
PDF 作成ソフトによって、異なる構造になる可能性があります。
:::

対象 PDF に対して、PDF からの文字抽出ソフトで文字抽出を行うと、下記結果が得られます。

```
A B C
A B C
```

### セル結合あり

A1 と B1 をセル結合した状態にします。

![Excel-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/854f4021-060a-8364-2e89-175969ba8731.png)

Excel から PDF 出力して、PDF を itext/rups でストリーム確認してみます。

![RUPS-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/432a4f4d-fc0a-f9da-cb7d-388aa8f4ff7e.png)

１個目のテキストオブジェクトは、セル結合を除いた１行目データです。
２個目のテキストオブジェクトは、セル結合なしと同一です。
３個目のテキストオブジェクトは、セル結合されている A1-B1 セルだと確認できます。

Excel から PDF を作成すると、まず、 セル結合を除いて、すべての行データをテキストオブジェクトにした後、セル結合されているセルひとつずつを、テキストオブジェクトにしているようです。

::: note
PDF 作成ソフトによって、異なる構造になる可能性があります。
:::

対象 PDF に対して、PDF からの文字抽出ソフトで文字抽出を行うと、下記結果が得られます。

```
C
A B C
AB
```

以上で、Excelセル結合によるテキストオブジェクトに対する影響を、PDF ストリームで確認できました。

::: note
後述「おまけ」の結果では、セル結合されていない同一行の複数テキストオブジェクトが１行にまとめて文字抽出されています。
しかし、「Excelセル結合のワナ」記載例を見るとわかるように、`2025`　`1`　`25` と連続している同一行のセル結合単位の複数テキストオブジェクトが、１行にまとめて文字抽出されていません。
このため、テキストオブジェクトを座標情報で並び替えるだけでは解決しませんね。
:::

### おまけ

「セル結合なし」で利用した Excel に対して、B1 セルのフォント種類とサイズを変更して、フォント変更に対する影響も一応確認することとします。

![Excel-01-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963267/5163da03-69bf-6aae-2057-2ed557e0a4a0.png)

Excel から PDF 出力して、PDF を itext/rups でストリーム確認してみます。
テキストオブジェクトは下記４個が出力されていました。

- A1セルの文字列
- B1セルの文字列
- C1セルの文字列
- ２行目（A2 + B2 + C2）の文字列

::: note
PDF 作成ソフトによって、異なる構造になる可能性があります。
:::

対象 PDF に対して、PDF からの文字抽出ソフトで文字抽出を行うと、下記結果が得られます。

```
A B C
A B C
```

フォント変更でテキストオブジェクトが分離されていても、同一行のテキストオブジェクトが連続していれば、１行のデータとして処理してくれるようです。

::: note
PDF からの文字抽出ソフトによって、異なる結果になる可能性があります。
:::

## まとめ

「PDFファイルは印刷した結果のみを保証するもの」という前提なので、期待する文字抽出を得たいなら、PDF からの文字抽出ソフト側で対処すべきということになります。

「Excelセル結合のワナ」については、PDF からの文字抽出ソフトに、テキストオブジェクトを座標情報で並び替える機能と、セル結合テキストオブジェクトでも連続していれば１行にまとめる機能が必要となります。

::: note
このような機能を持つ、PDF からの文字抽出ソフトは、当時、確認しきれませんでした。

PDF からの文字抽出ソフトを利用することを検討されている場合は、Excel セル結合に対する動作を確認することをお勧めします。
:::

また、意図している文字列が取得できないパターンとしては、下記ケースがあげられていたので、用途にあわせて確認が必要です。

- ページ内が段組み、コラム、表、図などのブロックで分割・構成されているとき、ブロックとして適切に認識することができない

::: note
こちらと「Excelセル結合のワナ」双方を両立する有効な解決策は、AI で文脈解析などでないと実現できそうもないですね。
:::