Introduzione
Aspose.PDF FOSS per Java è una libreria Java rilasciata sotto licenza MIT per creare e modificare documenti PDF. Le sue classi sono organizzate nel pacchetto org.aspose.pdf e nei suoi sotto-pacchetti (org.aspose.pdf.annotations, org.aspose.pdf.forms, org.aspose.pdf.facades e altri), e Document è il punto d’ingresso per la maggior parte dei flussi di lavoro. La libreria non ha dipendenze runtime di terze parti; l’unica dipendenza nella sua build Maven è JUnit, con ambito test.
L’annuncio della library, il post delle facade, e il post di page-editing coprono già la creazione di documenti, i campi modulo, le classi facade per estrazione, crittografia e timbratura, e le operazioni di pagina con PdfFileEditor. Questo post copre altre cinque aree dello stesso API che quei post non mostrano: annotazioni di markup testuale, note a testo libero, azioni a livello di documento, un controllo di dimensione sulla decodifica dei flussi e la registrazione diagnostica.
Ogni area è un piccolo API autonomo. Le sezioni seguenti mostrano le chiamate, i valori predefiniti e i casi limite che i test della libreria determinano.
Caratteristiche chiave
Annotazioni di markup testuale
HighlightAnnotation, UnderlineAnnotation, StrikeOutAnnotation e SquigglyAnnotation accettano ciascuno un Page e un Rectangle. Il costruttore ricava i punti quad dell’annotazione dal rettangolo, così getQuadPoints() restituisce otto valori senza alcun calcolo manuale. Per il rettangolo (100, 200, 300, 250) il risultato è [100, 250, 300, 250, 100, 200, 300, 200]: in alto a sinistra, in alto a destra, in basso a sinistra, poi in basso a destra. setQuadPoints() sostituisce i valori derivati con il tuo array di otto valori, e un’annotazione ricostruita da un dizionario esistente conserva i punti quad già memorizzati lì. getSubtype() restituisce il nome del sottotipo PDF: Highlight, Underline, StrikeOut o Squiggly.
Costruire un’annotazione non la allega alla pagina. Aggiungila con 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");
}
Callout di Testo Libero
FreeTextAnnotation posiziona il testo direttamente su una pagina. Il suo costruttore a tre argomenti accetta un DefaultAppearance, che contiene il nome del font, la dimensione del font e il colore del testo. Tre proprietà modellano il callout:
setIntent()accetta unFreeTextIntent:FreeText,FreeTextCalloutoFreeTextTypeWriter. Una nuova annotazione segnalaUndefined, e passandonullla riporta a quello stato.setCallout()accetta la linea del callout come un array di due o tre punti{x, y}. Un array di qualsiasi altra lunghezza viene ignorato e il callout esistente rimane al suo posto;nullrimuove il callout.setEndingStyle()accetta un valoreLineEndingcomeOpenArrowoDiamond. Una nuova annotazione segnalaLineEnding.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");
}
Il dizionario dell’annotazione salvata memorizza questi valori come /IT, /CL e /LE.
Azioni a Livello di Documento
Document.getActions() restituisce una vista DocumentActions del catalogo del documento. setOpenAction() memorizza un’azione nella voce /OpenAction del catalogo. Cinque ulteriori trigger, setBeforeClosing(), setBeforeSaving(), setAfterSaving(), setBeforePrinting() e setAfterPrinting(), sono memorizzati in modo indipendente nel dizionario additional-actions /AA del catalogo.
Ogni getter restituisce null finché il suo trigger non è impostato. Passare null a un setter rimuove quella voce, e rimuovere l’ultimo trigger rimuove anche il dizionario /AA. Le azioni sono istanze PdfAction; GoToURIAction è un alias di UriAction, e il suo getType() restituisce URI. L’oggetto DocumentActions è una vista live, quindi una chiamata successiva a getActions() vede le modifiche apportate da una precedente, e i trigger vengono letti nuovamente quando il file salvato viene riaperto.
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");
}
Limiti di Decodifica per i Filtri di Stream
I flussi PDF sono memorizzati in forma codificata, e un flusso corrotto o dannoso può espandersi a molto più della sua dimensione memorizzata. DecodeLimits è una guardia condivisa dai filtri FlateDecode, LZWDecode e RunLengthDecode. Quando l’output decodificato di un flusso supera il limite, il filtro lancia DecodeSizeLimitException, una sottoclasse di IOException, invece di decodificare fino a esaurire l’heap.
Il limite predefinito è 256MB per flusso decodificato (DecodeLimits.DEFAULT_MAX_DECODED_BYTES). Per modificarlo, impostare la proprietà di sistema indicata da DecodeLimits.PROPERTY, che è aspose.pdf.maxDecodedStreamBytes, a una dimensione in byte; un valore di 0 o inferiore disabilita la guardia. La proprietà viene letta a ogni decodifica, quindi può essere modificata a runtime.
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;
}
}
I flussi al di sotto del limite vengono decodificati come di consueto. FlateFilter e RunLengthFilter effettuano entrambi un round-trip dei dati tramite encode() e decode() quando l’output rimane entro il limite.
Registrazione Diagnostica
La libreria registra tramite java.util.logging sotto il logger org.aspose.pdf ed è silenziosa per impostazione predefinita: il livello è OFF. AsposePdfLogging attiva la registrazione.
setLevel(Level)imposta il livello dal codice;nullrestituisce la libreria aOFF.getLevel()lo legge nuovamente.- La proprietà di sistema
aspose.pdf.log(disponibile anche comeAsposePdfLogging.LOG_PROPERTY) la imposta dalla riga di comando.configureFromSystemProperty()applica la proprietà e viene eseguita anche quando la classe viene caricata. I valorionewarningselezionanoWARNING,verboseselezionaFINE,debugselezionaALL, qualsiasi nomejava.util.logging.LevelcomeSEVEREè accettato, e un valore non riconosciuto ripristina aOFF.
WARNING consente i warning del motore; FINE, l’impostazione verbose, consente anche i dettagli di recupero del parser. AsposePdfLogging modifica solo il sottoalbero del logger org.aspose.pdf. Non modifica il livello del logger radice, e il logger della libreria non passa i record ai gestori del logger radice. Se il logging è abilitato e nessun gestore è collegato al logger della libreria, viene installato un gestore console.
// 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
Avvio rapido
Aggiungi la dipendenza al tuo build:
<dependency>
<groupId>org.aspose</groupId>
<artifactId>aspose-pdf-foss</artifactId>
<version>26.8.0</version>
</dependency>Il seguente esempio crea una pagina, aggiunge un’evidenziazione e una nota di testo libero, e salva il documento:
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");
}
Formati supportati
Supporto dei formati come confermato dalle opzioni di caricamento e salvataggio della libreria e dai dispositivi di rendering:
| Formato | Estensione | Leggi | Scrivi |
|---|---|---|---|
| ✓ | ✓ | ||
| HTML | html | ✓ | ✓ |
| DOCX | docx | ✓ | ✓ |
| DOC | doc | ✓ | ✓ |
| XFDF | xfdf | ✓ | ✓ |
| BMP | bmp | — | ✓ |
| GIF | gif | — | ✓ |
| JPEG | jpeg | — | ✓ |
| TIFF | tiff | — | ✓ |
| Text | txt | — | ✓ |
Open Source e Licenze
Aspose.PDF FOSS per Java è rilasciato sotto licenza MIT, che consente l’uso commerciale, la modifica e la redistribuzione. Il codice sorgente e il tracciatore di problemi sono su github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java. La libreria richiede Java 11 o versioni successive.