You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.3 KiB
139 lines
5.3 KiB
|
1 month ago
|
# Cursor プロジェクト説明(iText7 で PDF に「メモ用レイヤー」を 2 つ追加)
|
||
|
|
|
||
|
|
## 目的
|
||
|
|
|
||
|
|
既存の PDF に **OCG(Optional Content Group=レイヤー)を 2 つ** 追加し、後からそのレイヤーにメモ(テキスト/図形/注釈)を書き込めるようにします。
|
||
|
|
Acrobat の「レイヤー」パネルで表示・非表示を切り替えられる **「メモ1」「メモ2」** を作成します。
|
||
|
|
|
||
|
|
## ゴール/受け入れ基準
|
||
|
|
|
||
|
|
* 既存 PDF を入力に取り、出力 PDF のカタログに **OCProperties/OCGs** が作成されていること(2 つの OCG)。
|
||
|
|
* Acrobat / PDF-XChange 等で **レイヤー「メモ1」「メモ2」** が確認でき、ON/OFF 切り替えが可能。
|
||
|
|
* 追加サンプルとして、各レイヤーに 1 行テキストを描画(または四角形)できること。
|
||
|
|
* 既存ページのコンテンツは変更しない(上に重ねるだけ)。
|
||
|
|
|
||
|
|
## 技術ポイント(PDF 構造)
|
||
|
|
|
||
|
|
* iText7 では `PdfLayer`(= OCG)を生成し、`PdfCanvas.beginLayer(layer) ... endLayer()` の間で描画したコンテンツはそのレイヤーに属します。
|
||
|
|
* 既存 PDF を開いてレイヤーを「追加」するだけなら、iText が **Catalog/OCProperties** を自動で拡張してくれます。
|
||
|
|
* 初期表示状態(ON/OFF)は `layer.setOn(true/false)` で制御可能。
|
||
|
|
|
||
|
|
## 環境
|
||
|
|
|
||
|
|
* 言語:Java 17(推奨 11+)
|
||
|
|
* ビルド:Maven もしくは Gradle
|
||
|
|
* ライブラリ:iText7(kernel / layout)
|
||
|
|
|
||
|
|
* Maven:
|
||
|
|
|
||
|
|
```xml
|
||
|
|
<dependency>
|
||
|
|
<groupId>com.itextpdf</groupId>
|
||
|
|
<artifactId>kernel</artifactId>
|
||
|
|
<version>8.0.2</version>
|
||
|
|
</dependency>
|
||
|
|
<dependency>
|
||
|
|
<groupId>com.itextpdf</groupId>
|
||
|
|
<artifactId>layout</artifactId>
|
||
|
|
<version>8.0.2</version>
|
||
|
|
</dependency>
|
||
|
|
```
|
||
|
|
* Gradle:
|
||
|
|
|
||
|
|
```gradle
|
||
|
|
implementation "com.itextpdf:kernel:8.0.2"
|
||
|
|
implementation "com.itextpdf:layout:8.0.2"
|
||
|
|
```
|
||
|
|
|
||
|
|
## プロジェクト構成(推奨)
|
||
|
|
|
||
|
|
```
|
||
|
|
pdf-memo-layers/
|
||
|
|
├─ README.md
|
||
|
|
├─ build.gradle or pom.xml
|
||
|
|
├─ src/
|
||
|
|
│ └─ main/java/
|
||
|
|
│ └─ co/jp/techsor/pdf/
|
||
|
|
│ ├─ App.java // CLI エントリ
|
||
|
|
│ ├─ PdfMemoLayerService.java // レイヤー作成・描画の中核
|
||
|
|
│ ├─ LayerDrawingOptions.java // 文字/図形の描画オプション
|
||
|
|
│ └─ util/
|
||
|
|
│ └─ PdfUtils.java // 共通ユーティリティ
|
||
|
|
└─ samples/
|
||
|
|
├─ input.pdf
|
||
|
|
└─ output.pdf (生成物)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 主要ユースケース
|
||
|
|
|
||
|
|
1. **レイヤーだけを追加**(後で編集者が注釈・図形を載せる)
|
||
|
|
2. **レイヤーにテキスト/図形を同時に配置**(例:右下に “Memo Layer”)
|
||
|
|
3. **初期状態の切替**(メモ1=ON、メモ2=OFF など)
|
||
|
|
|
||
|
|
## CLI 仕様(例)
|
||
|
|
|
||
|
|
```
|
||
|
|
java -jar pdf-memo-layers.jar \
|
||
|
|
--in samples/input.pdf \
|
||
|
|
--out samples/output.pdf \
|
||
|
|
--layer1 "メモ1" --layer2 "メモ2" \
|
||
|
|
--draw "text:1,100,700,メモ1のサンプル" \
|
||
|
|
--draw "rect:2,50,50,200,60" \
|
||
|
|
--l2-on=false
|
||
|
|
```
|
||
|
|
|
||
|
|
* `--draw` は複数指定可。形式:
|
||
|
|
|
||
|
|
* `text:<layerIndex(1|2)>,<x>,<y>,<content>`
|
||
|
|
* `rect:<layerIndex(1|2)>,<x>,<y>,<w>,<h>`
|
||
|
|
* `--l2-on=false` のように初期表示を切替。
|
||
|
|
|
||
|
|
## 実装概略(擬似コード)
|
||
|
|
|
||
|
|
```java
|
||
|
|
try (PdfDocument pdf =
|
||
|
|
new PdfDocument(new PdfReader(inPath), new PdfWriter(outPath))) {
|
||
|
|
|
||
|
|
// 1) レイヤー(OCG)作成
|
||
|
|
PdfLayer memo1 = new PdfLayer("メモ1", pdf);
|
||
|
|
memo1.setOn(true); // 初期表示 ON
|
||
|
|
PdfLayer memo2 = new PdfLayer("メモ2", pdf);
|
||
|
|
memo2.setOn(false); // 初期表示 OFF(例)
|
||
|
|
|
||
|
|
// 2) 必要に応じて描画(各ページの上に重ねる)
|
||
|
|
PdfPage page1 = pdf.getPage(1);
|
||
|
|
PdfCanvas canvas1 = new PdfCanvas(page1);
|
||
|
|
canvas1.beginLayer(memo1);
|
||
|
|
// テキスト描画(iText7 layout を使う場合は Canvas を併用)
|
||
|
|
try (Canvas c = new Canvas(canvas1, page1.getPageSize())) {
|
||
|
|
c.showTextAligned("メモ1のサンプル", 100, 700, TextAlignment.LEFT);
|
||
|
|
}
|
||
|
|
canvas1.endLayer();
|
||
|
|
|
||
|
|
PdfPage page2 = pdf.getPage(2);
|
||
|
|
PdfCanvas canvas2 = new PdfCanvas(page2);
|
||
|
|
canvas2.beginLayer(memo2);
|
||
|
|
canvas2.rectangle(50, 50, 200, 60);
|
||
|
|
canvas2.stroke();
|
||
|
|
canvas2.endLayer();
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## テスト手順
|
||
|
|
|
||
|
|
1. `samples/input.pdf` を用意し、CLI で実行して `samples/output.pdf` を生成。
|
||
|
|
2. Acrobat で `output.pdf` を開き、**表示 → ナビゲーションパネル → レイヤー** を表示。
|
||
|
|
3. 「メモ1」「メモ2」の存在と ON/OFF の切り替えで描画が出入りすることを確認。
|
||
|
|
|
||
|
|
## エッジケースと対策
|
||
|
|
|
||
|
|
* **暗号化 PDF**:所有者パスワードが必要。`ReaderProperties`/`WriterProperties` で設定。
|
||
|
|
* **透明度・ブレンド**:必要なら `PdfExtGState` を併用して半透明表現。
|
||
|
|
* **注釈に載せたい**:注釈は OCG 直付けできないため、描画をレイヤーに、注釈は通常オブジェクトとして扱う(見た目同期が必要)。
|
||
|
|
* **長文テキスト**:`layout` の `Paragraph` を使用し、行送りとフォント設定を行う。
|
||
|
|
|
||
|
|
## ライセンス注意
|
||
|
|
|
||
|
|
iText 7 は AGPL もしくは商用ライセンスです。社内/顧客配布要件に合わせてライセンス選定を行ってください。
|
||
|
|
|