はじめに

Aspose.PDF FOSS for Java は、MIT ライセンスの Java ライブラリで、PDF ドキュメントの作成と編集が可能です。そのクラスは org.aspose.pdf パッケージとサブパッケージ(org.aspose.pdf.annotations、org.aspose.pdf.forms、org.aspose.pdf.facades など)に整理されており、Document がほとんどのワークフローのエントリーポイントです。このライブラリはサードパーティのランタイム依存関係がなく、Maven ビルドでの唯一の依存はテストスコープの JUnit です。

すでに library announcement、facades post、および page-editing post では、ドキュメント作成、フォームフィールド、抽出・暗号化・スタンプ用のファサードクラス、そして PdfFileEditor を用いたページ操作が取り上げられています。本記事では、同じ API のうち、これらの記事で示されていない 5 つの領域、すなわちテキストマークアップ注釈、フリーテキスト呼び出し、ドキュメントレベルのアクション、ストリームデコード時のサイズガード、診断ロギングについて解説します。

各領域は小さく、自己完結型の API です。以下のセクションでは、呼び出し方法、デフォルト設定、およびライブラリ自身のテストで確認されたエッジケースを示します。


主な機能

テキストマークアップ注釈

HighlightAnnotation、UnderlineAnnotation、StrikeOutAnnotation、および SquigglyAnnotation はそれぞれ Page と Rectangle を受け取ります。コンストラクタは矩形から注釈の四隅座標を導出するため、getQuadPoints() は手動計算なしで 8 つの値を返します。矩形 (100, 200, 300, 250) に対して結果は [100, 250, 300, 250, 100, 200, 300, 200] となります:左上、右上、左下、右下の順です。setQuadPoints() は導出された値を独自の 8 要素配列に置き換え、既存の辞書から再構築された注釈はそこに保存されている四隅座標を保持します。getSubtype() は PDF のサブタイプ名を返します:Highlight、Underline、StrikeOut、または Squiggly。

アノテーションを作成してもページに添付されません。page.getAnnotations().add(...)で追加します。

try (Document doc = new Document()) {
    Page page = doc.getPages().add();

    HighlightAnnotation highlight = new HighlightAnnotation(page, new Rectangle(100, 200, 300, 250));
    double[] quadPoints = highlight.getQuadPoints();

    UnderlineAnnotation underline = new UnderlineAnnotation(page, new Rectangle(50, 100, 200, 120));
    StrikeOutAnnotation strikeOut = new StrikeOutAnnotation(page, new Rectangle(50, 140, 200, 160));
    SquigglyAnnotation squiggly = new SquigglyAnnotation(page, new Rectangle(50, 180, 200, 200));

    page.getAnnotations().add(highlight);
    page.getAnnotations().add(underline);
    page.getAnnotations().add(strikeOut);
    page.getAnnotations().add(squiggly);
    doc.save("markup.pdf");
}

フリーテキスト・コールアウト

FreeTextAnnotationはテキストをページ上に直接配置します。その3引数コンストラクタはDefaultAppearanceを受け取り、フォント名、フォントサイズ、テキストカラーを保持します。3つのプロパティがコールアウトを形成します:

  • setIntent()はFreeTextIntentを受け取ります:FreeText、FreeTextCallout、またはFreeTextTypeWriter。新しいアノテーションはUndefinedを報告し、nullを渡すとその状態に戻ります。
  • setCallout()はコールアウトラインを2つまたは3つの{x, y}ポイントの配列として受け取ります。その他の長さの配列は無視され、既存のコールアウトはそのまま残ります;nullはコールアウトを削除します。
  • setEndingStyle()はOpenArrowやDiamondのようなLineEnding値を受け取ります。新しいアノテーションはLineEnding.Noneを報告します。
try (Document doc = new Document()) {
    Page page = doc.getPages().add();
    DefaultAppearance da = new DefaultAppearance("Helv", 10, Color.BLACK);
    FreeTextAnnotation note = new FreeTextAnnotation(page, new Rectangle(50, 50, 200, 100), da);

    note.setContents("Check this value");
    note.setIntent(FreeTextIntent.FreeTextCallout);
    note.setCallout(new double[][] {{10, 10}, {50, 50}, {100, 100}});
    note.setEndingStyle(LineEnding.OpenArrow);

    page.getAnnotations().add(note);
    doc.save("callout.pdf");
}

保存されたアノテーション辞書はこれらの値を/IT、/CL、および/LEとして格納します。

ドキュメントレベルのアクション

Document.getActions() はドキュメントカタログの DocumentActions ビューを返します。setOpenAction() はカタログの /OpenAction エントリにアクションを格納します。さらに5つのトリガー、setBeforeClosing()、setBeforeSaving()、setAfterSaving()、setBeforePrinting()、および setAfterPrinting() は、カタログの /AA additional-actions 辞書に個別に格納されます。

各ゲッターはトリガーが設定されるまで null を返します。null をセッターに渡すとそのエントリが削除され、最後のトリガーを削除すると /AA 辞書も削除されます。アクションは PdfAction インスタンスです。GoToURIAction は UriAction のエイリアスであり、その getType() は URI を返します。DocumentActions オブジェクトはライブビューであるため、後からの getActions() の呼び出しは前の呼び出しで行われた変更を反映し、保存されたファイルを再度開くとトリガーが読み戻されます。

try (Document doc = new Document()) {
    doc.getPages().add();
    DocumentActions actions = doc.getActions();

    actions.setOpenAction(new GoToURIAction("https://example.com"));
    actions.setBeforeSaving(new GoToURIAction("https://example.com/saving"));

    PdfAction open = doc.getActions().getOpenAction();
    if (open instanceof UriAction) {
        System.out.println(((UriAction) open).getUri());
    }

    actions.setBeforeSaving(null);   // removes /WS; /AA is removed once it is empty
    doc.save("actions.pdf");
}

ストリームフィルタのデコード制限

PDF ストリームはエンコードされた形で保存されており、破損したり悪意のあるストリームは保存サイズをはるかに超えて膨張する可能性があります。DecodeLimits は FlateDecode、LZWDecode、RunLengthDecode フィルタで共有されるガードです。ストリームのデコード出力が上限を超えると、フィルタはヒープが枯渇するまでデコードを続ける代わりに、IOException のサブクラスである DecodeSizeLimitException をスローします。

デフォルトの上限はデコードされたストリームあたり 256MB(DecodeLimits.DEFAULT_MAX_DECODED_BYTES)です。これを変更するには、DecodeLimits.PROPERTY という名前のシステムプロパティ(aspose.pdf.maxDecodedStreamBytes)をバイト単位のサイズに設定します。0 以下の値にするとガードが無効になります。このプロパティは各デコード時に読み取られるため、実行時に変更可能です。

static byte[] decodeFlate(byte[] encoded) {
    // Lower the cap to 16 MB (16777216 bytes) for this process
    System.setProperty(DecodeLimits.PROPERTY, "16777216");
    try {
        return new FlateFilter().decode(encoded, null);
    } catch (IOException e) {
        // "FlateDecode: decoded output exceeds 16777216 bytes - likely a corrupt stream
        //  or decompression bomb (override with -Daspose.pdf.maxDecodedStreamBytes)"
        return null;
    }
}

上限未満のストリームは通常どおりデコードされます。FlateFilter と RunLengthFilter は、出力が上限内に収まる場合、encode() と decode() を介してデータを往復させます。

診断ロギング

このライブラリは org.aspose.pdf ロガーの下で java.util.logging を通じてログを記録し、デフォルトではサイレントです:レベルは OFF です。AsposePdfLogging はロギングを有効にします。

  • setLevel(Level) はコードからレベルを設定します; null はライブラリを OFF に戻します。getLevel() はそれを読み戻します。
  • aspose.pdf.log システムプロパティ(AsposePdfLogging.LOG_PROPERTY としても利用可能)はコマンドラインからそれを設定します。configureFromSystemProperty() はプロパティを適用し、クラスがロードされるときにも実行されます。値 on と warning は WARNING を選択し、verbose は FINE を選択し、debug は ALL を選択し、java.util.logging.Level 名(例: SEVERE)はすべて受け入れられ、認識されない値は OFF にフォールバックします。

WARNING はエンジンの警告を通過させます; FINE、verbose 設定もパーサーのリカバリ詳細を通過させます。AsposePdfLogging は org.aspose.pdf ロガーのサブツリーのみを変更します。ルートロガーのレベルは変更せず、ライブラリロガーはレコードをルートロガーのハンドラに渡しません。ロギングが有効で、ライブラリロガーにハンドラがアタッチされていない場合、コンソールハンドラがインストールされます。

// Equivalent to starting the JVM with -Daspose.pdf.log=warning
AsposePdfLogging.setLevel(Level.WARNING);

System.setProperty(AsposePdfLogging.LOG_PROPERTY, "verbose");
AsposePdfLogging.configureFromSystemProperty();
System.out.println(AsposePdfLogging.getLevel());   // FINE

クイックスタート

ビルドに依存関係を追加してください:

<dependency>
  <groupId>org.aspose</groupId>
  <artifactId>aspose-pdf-foss</artifactId>
  <version>26.8.0</version>
</dependency>

以下の例はページを作成し、ハイライトとフリーテキストのコールアウトを追加して、ドキュメントを保存します:

import org.aspose.pdf.*;
import org.aspose.pdf.annotations.*;

try (Document doc = new Document()) {
    Page page = doc.getPages().add();

    page.getAnnotations().add(new HighlightAnnotation(page, new Rectangle(100, 200, 300, 250)));

    FreeTextAnnotation note = new FreeTextAnnotation(page, new Rectangle(50, 50, 200, 100),
            new DefaultAppearance("Helv", 10, Color.BLACK));
    note.setContents("Check this value");
    note.setIntent(FreeTextIntent.FreeTextCallout);
    note.setCallout(new double[][] {{10, 10}, {50, 50}, {100, 100}});
    page.getAnnotations().add(note);

    doc.save("core-features.pdf");
}

サポートされているフォーマット

ライブラリのロードおよびセーブオプション、そしてレンダリングデバイスで確認されたフォーマットサポート:

フォーマット拡張子読み取り書き込み
PDFpdf✓✓
HTMLhtml✓✓
DOCXdocx✓✓
DOCdoc✓✓
XFDFxfdf✓✓
BMPbmp—✓
GIFgif—✓
JPEGjpeg—✓
TIFFtiff—✓
Texttxt—✓

オープンソース & ライセンス

Aspose.PDF FOSS for Java は MIT ライセンスの下でリリースされており、商用利用、改変、再配布が許可されています。ソースコードとイシュー トラッカーは github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java にあります。ライブラリは Java 11 以降を対象としています。


はじめに

関連リソース