Вступ

Aspose.PDF FOSS для Java — це бібліотека Java з ліцензією MIT для створення та редагування PDF-документів. Її класи організовані у пакеті org.aspose.pdf та його підпакетах (org.aspose.pdf.annotations, org.aspose.pdf.forms, org.aspose.pdf.facades та інші), а Document є точкою входу для більшості робочих процесів. Бібліотека не має сторонніх залежностей під час виконання; єдина залежність у її Maven-збірці — це JUnit у тестовому діапазоні.

Оголошення library, допис facades та допис page-editing вже охоплюють створення документів, поля форм, фасадні класи для вилучення, шифрування та штампування, а також операції зі сторінками за допомогою PdfFileEditor. Цей допис розглядає п’ять інших областей того ж API, які не продемонстровані в цих дописах: анотації розмітки тексту, вільні текстові підписи, дії рівня документа, захист розміру під час декодування потоку та діагностичне журналювання.

Кожна область — це невелика, автономна API. Нижче наведені розділи, які показують виклики, типові значення та крайові випадки, зафіксовані у власних тестах бібліотеки.


Ключові особливості

Анотації розмітки тексту

HighlightAnnotation, UnderlineAnnotation, StrikeOutAnnotation та SquigglyAnnotation кожен приймає Page і Rectangle. Конструктор виводить квадрокоординати анотації з прямокутника, тому getQuadPoints() повертає вісім значень без жодних ручних обчислень. Для прямокутника (100, 200, 300, 250) результат становить [100, 250, 300, 250, 100, 200, 300, 200]: верхній лівий, верхній правий, нижній лівий, потім нижній правий. setQuadPoints() замінює отримані значення вашим власним масивом з восьми елементів, а анотація, відновлена з існуючого словника, зберігає вже збережені там квадрокоординати. 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 розміщує текст безпосередньо на сторінці. Його конструктор з трьома аргументами приймає DefaultAppearance, який містить назву шрифту, розмір шрифту та колір тексту. Три властивості формують підпис:

  • setIntent() приймає FreeTextIntent: FreeText, FreeTextCallout або FreeTextTypeWriter. Нова анотація повідомляє Undefined, а передача null повертає її в цей стан.
  • setCallout() приймає лінію підпису як масив з двох або трьох точок {x, y}. Масив будь-якої іншої довжини ігнорується, і існуючий підпис залишається на місці; null видаляє підпис.
  • setEndingStyle() приймає значення LineEnding, наприклад OpenArrow або Diamond. Нова анотація повідомляє 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 каталогу. П’ять інших тригерів, setBeforeClosing(), setBeforeSaving(), setAfterSaving(), setBeforePrinting() та setAfterPrinting(), зберігаються окремо у словнику додаткових дій /AA каталогу.

Кожен getter повертає null, доки його тригер не встановлено. Передача null у setter видаляє цей запис, а видалення останнього тригеру також видаляє словник /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. Коли декодований вивід потоку перевищує ліміт, фільтр викидає DecodeSizeLimitException, підклас IOException, замість того, щоб декодувати до вичерпання heap.

Типовий ліміт становить 256МБ на декодований потік (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(), коли вихід залишається в межах ліміту.

Діагностичне логування

Бібліотека веде журнал через java.util.logging під логгером org.aspose.pdf і за замовчуванням мовчить: рівень — 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 для Java випущено під ліцензією MIT, яка дозволяє комерційне використання, модифікацію та розповсюдження. Вихідний код і трекер проблем розташовані за адресою github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java. Бібліотека орієнтована на Java 11 або новішу.


Перші кроки

Пов’язані ресурси