Introdução
Aspose.PDF FOSS para Java é uma biblioteca Java licenciada sob MIT para criar e editar documentos PDF. Suas classes estão organizadas sob o pacote org.aspose.pdf e seus subpacotes (org.aspose.pdf.annotations, org.aspose.pdf.forms, org.aspose.pdf.facades e outros), e Document é o ponto de entrada para a maioria dos fluxos de trabalho. A biblioteca não tem dependências de tempo de execução de terceiros; a única dependência em sua construção Maven é o JUnit, no escopo de teste.
O anúncio da biblioteca, o post sobre fachadas, e o post sobre edição de páginas já cobrem criação de documentos, campos de formulário, as classes fachada para extração, criptografia e carimbo, e operações de página com PdfFileEditor. Este post cobre cinco outras áreas do mesmo API que esses posts não demonstram: anotações de marcação de texto, chamadas de texto livre, ações em nível de documento, uma proteção de tamanho na decodificação de streams e registro de diagnóstico.
Cada área é um pequeno API autocontido. As seções abaixo mostram as chamadas, os valores padrão e os casos limites que os próprios testes da biblioteca definem.
Recursos Principais
Anotações de Marcação de Texto
HighlightAnnotation, UnderlineAnnotation, StrikeOutAnnotation e SquigglyAnnotation recebem cada um um Page e um Rectangle. O construtor deriva os quad points da anotação a partir do retângulo, portanto getQuadPoints() retorna oito valores sem nenhum cálculo manual. Para o retângulo (100, 200, 300, 250) o resultado é [100, 250, 300, 250, 100, 200, 300, 200]: superior esquerdo, superior direito, inferior esquerdo, depois inferior direito. setQuadPoints() substitui os valores derivados pelos seus próprios oito valores em array, e uma anotação reconstruída a partir de um dicionário existente mantém os quad points já armazenados lá. getSubtype() retorna o nome do subtipo PDF: Highlight, Underline, StrikeOut ou Squiggly.
Construir uma anotação não a anexa à página. Adicione-a com 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");
}
Chamadas de Texto Livre
FreeTextAnnotation coloca texto diretamente em uma página. Seu construtor de três argumentos recebe um DefaultAppearance, que contém o nome da fonte, o tamanho da fonte e a cor do texto. Três propriedades moldam a chamada:
setIntent()recebe umFreeTextIntent:FreeText,FreeTextCalloutouFreeTextTypeWriter. Uma nova anotação relataUndefined, e passarnulldevolve-a a esse estado.setCallout()recebe a linha da chamada como um array de dois ou três pontos{x, y}. Um array de qualquer outro tamanho é ignorado e a chamada existente permanece no local;nullremove a chamada.setEndingStyle()recebe um valorLineEndingcomoOpenArrowouDiamond. Uma nova anotação relataLineEnding.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");
}
O dicionário de anotação salvo armazena esses valores como /IT, /CL e /LE.
Ações ao Nível de Documento
Document.getActions() retorna uma visão DocumentActions do catálogo de documentos. setOpenAction() armazena uma ação na entrada /OpenAction do catálogo. Cinco gatilhos adicionais, setBeforeClosing(), setBeforeSaving(), setAfterSaving(), setBeforePrinting() e setAfterPrinting(), são armazenados independentemente no dicionário de ações adicionais /AA do catálogo.
Cada getter retorna null até que seu gatilho seja definido. Passar null para um setter remove essa entrada, e remover o último gatilho também remove o dicionário /AA. As ações são instâncias PdfAction; GoToURIAction é um alias de UriAction, e seu getType() retorna URI. O objeto DocumentActions é uma visão ao vivo, de modo que uma chamada posterior a getActions() vê as alterações feitas por uma chamada anterior, e os gatilhos são lidos novamente quando o arquivo salvo é aberto novamente.
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");
}
Limites de Decodificação para Filtros de Fluxo
Os fluxos PDF são armazenados em forma codificada, e um fluxo corrompido ou malicioso pode expandir para muito mais do que seu tamanho armazenado. DecodeLimits é uma proteção compartilhada pelos filtros FlateDecode, LZWDecode e RunLengthDecode. Quando a saída decodificada de um fluxo excede o limite, o filtro lança DecodeSizeLimitException, uma subclasse de IOException, em vez de decodificar até que o heap seja esgotado.
O limite padrão é 256MB por fluxo decodificado (DecodeLimits.DEFAULT_MAX_DECODED_BYTES). Para alterá-lo, defina a propriedade do sistema nomeada por DecodeLimits.PROPERTY, que é aspose.pdf.maxDecodedStreamBytes, para um tamanho em bytes; um valor de 0 ou menor desativa a proteção. A propriedade é lida a cada decodificação, portanto pode ser alterada em tempo de execução.
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;
}
}
Fluxos dentro do limite decodificam normalmente. FlateFilter e RunLengthFilter ambos realizam round-trip de dados através de encode() e decode() quando a saída permanece dentro do limite.
Registro de Diagnóstico
A biblioteca registra através de java.util.logging no logger org.aspose.pdf e permanece silenciosa por padrão: o nível é OFF. AsposePdfLogging ativa o registro.
setLevel(Level)define o nível a partir do código;nulldevolve a biblioteca paraOFF.getLevel()lê de volta.- A propriedade de sistema
aspose.pdf.log(também disponível comoAsposePdfLogging.LOG_PROPERTY) define-a a partir da linha de comando.configureFromSystemProperty()aplica a propriedade e também é executada quando a classe é carregada. Os valoresonewarningselecionamWARNING,verboseselecionaFINE,debugselecionaALL, qualquer nomejava.util.logging.LevelcomoSEVEREé aceito, e um valor não reconhecido volta paraOFF.
WARNING permite que os avisos do motor passem; FINE, a configuração verbose, também permite que os detalhes de recuperação do analisador passem. AsposePdfLogging altera apenas a subárvore do logger org.aspose.pdf. Não altera o nível do logger raiz, e o logger da biblioteca não encaminha registros para os manipuladores do logger raiz. Se o registro estiver habilitado e nenhum manipulador estiver anexado ao logger da biblioteca, um manipulador de console é instalado.
// 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
Início rápido
Adicione a dependência ao seu build:
<dependency>
<groupId>org.aspose</groupId>
<artifactId>aspose-pdf-foss</artifactId>
<version>26.8.0</version>
</dependency>O exemplo a seguir cria uma página, adiciona um destaque e uma chamada de texto livre, e salva o 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");
}
Formatos suportados
Suporte a formatos conforme confirmado pelas opções de carregamento e salvamento da biblioteca e pelos dispositivos de renderização:
| Formato | Extensão | Ler | Escrever |
|---|---|---|---|
| ✓ | ✓ | ||
| HTML | html | ✓ | ✓ |
| DOCX | docx | ✓ | ✓ |
| DOC | doc | ✓ | ✓ |
| XFDF | xfdf | ✓ | ✓ |
| BMP | bmp | — | ✓ |
| GIF | gif | — | ✓ |
| JPEG | jpeg | — | ✓ |
| TIFF | tiff | — | ✓ |
| Text | txt | — | ✓ |
Código Aberto e Licenciamento
Aspose.PDF FOSS para Java é lançado sob a licença MIT, que permite uso comercial, modificação e redistribuição. O código-fonte e o rastreador de problemas estão em github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java. A biblioteca tem como alvo Java 11 ou posterior.