BAEL-5943 Using Watermarks with iText in Java (#13178)
* BAEL-5943 Using Watermarks with iText in Java * BAEL-5943 Update * BAEL-5943 Update * BAEL-5943 Update
This commit is contained in:
parent
9215eee368
commit
966b349fba
Binary file not shown.
|
@ -0,0 +1,43 @@
|
||||||
|
%PDF-1.7
|
||||||
|
%âãÏÓ
|
||||||
|
5 0 obj
|
||||||
|
<</Filter/FlateDecode/Length 1013>>stream
|
||||||
|
xœ<EFBFBD>•[o7…ßõ+æ) l¢‹-éÑNÓú¡D@Ÿ©ÝY-+.¹æÅÆæ×÷¹’Û4À0[&g¾9sfø¼x<.Þÿº¢ÕšŽíbsO»ý¡:бY¼{0ºfzU<7A>ÕÉk—<02>.Ù3<C399>µ7ôÚ9r–©Q#…˜ú“á†Òà,Ž‡è•=ó’¢2<17>^<5E>N:Vtìxú}IZNvÉûqùóñïÅ;’ÏOÇÅçÅóÿ©vëj›©´}Ñ™
|
||||||
|
]tÔ:cÜ+uº§Æ½JÌ’€:g¸ÊÇ–d]Ì°8“·ÓIü4/lñ
Ž°:³7ã<14>›y¦»í¤T¼U…˜
"$|vì›–²4¢ÁDgœ=/¡š¿à_Ö²©DhÙ˜åT× B@‘±ó.<2E>;Q´WÆÌ#mvÕv•™ç|¦ÑE+j•<6A>*D]+´ÎyLm¤e¯:v·>)«‘(ä‹×Éhå©î”WuD=ÕpöI*þØqè´çyª,U¨>*4^œ˜{)hÃÀª 6:\ÿŠà9äkIö‡jèIE@”ûW@å„"+¨æãXZ>õŽZg(ìˆm<CB86>¶!>—„q„…m–ësb¶äZzZ@æâ9éú’ÓÃì¥ç›[ˆw¬‘Õµ³<÷{¸iâ±£xU²ÔÞe# ÌêjΡ›œ1\íâ¹WÚâ\è Ï¿ÊhèâCÀŽ‡žqžä~wU†ótÀyߎ¸0\xÌó$8b¶ØI×\‚µ¢ºpN|RE <!|µ^E°|!‘Ññ€ÚÂC›iÚÊPÜ‹î9Q¶º¤Ñq\晪Çþ„eÀf S@‹‘nIV\…êÐ)–Ñlp·¯è1eƒÏ3m`¡ÂÔsï¼æ .‘ºo{%Èšû+ç4¢¯C'[ç!²/Fb×F°üw…ÈÊE7Ï´‚<C2B4>ʦôœW]V<1F>™vrNÔ«svö`TÍÕ·áÖoáîöûj¿ËáþTØVFO„G¯¾jlKƒw-‡ <E280A1>EÀÖ¹x‚¢â9±/¶;t€}<7D>iÄ=¹Úë¦ÕlšR=ý–€õµséûµýf÷¡Ú—<C39A>û š<>QOÃtTî¤d!LK æL_Ò€ø¿c©'®ž`FI-s. ÜäÌA”ttÕ&<26>p‹îó wëëB“œÙÓòž!H÷GåkFÓÔ’Ž;Ëvª§'Ã<>¦Nߊ¦·J*ºIÚyˆÍö:ž8
B£°ÒY ‚¦e£YKw
|
||||||
|
69¿È<EFBFBD>I¸I êÚÕÀ®Ót9Ì@‡N×Ê3ì9O³º¯wÓ}Õ!7Ä
Šzö0Üm›¯Ku4¹WH{±òXJ“ÖňΗY<E28094>ía_îËöŠ<C3B6>®ËS†Ý·É`ºZ¶A¿pöÁ›óÿƽ×f
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<</Contents 5 0 R/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<</Font<</F1 6 0 R/F2 7 0 R>>>>/TrimBox[0 0 595 842]/Type/Page>>
|
||||||
|
endobj
|
||||||
|
1 0 obj
|
||||||
|
<</Pages 2 0 R/Type/Catalog>>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<</CreationDate(D:20221216134533Z)/ModDate(D:20221216134533Z)/Producer(iText® Core 7.2.4 \(AGPL version\) ©2000-2022 iText Group NV)>>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<</BaseFont/Times-Roman/Encoding/WinAnsiEncoding/Subtype/Type1/Type/Font>>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<</BaseFont/Helvetica/Encoding/WinAnsiEncoding/Subtype/Type1/Type/Font>>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<</Count 1/Kids[4 0 R]/Type/Pages>>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 8
|
||||||
|
0000000000 65535 f
|
||||||
|
0000001238 00000 n
|
||||||
|
0000001611 00000 n
|
||||||
|
0000001283 00000 n
|
||||||
|
0000001096 00000 n
|
||||||
|
0000000015 00000 n
|
||||||
|
0000001433 00000 n
|
||||||
|
0000001523 00000 n
|
||||||
|
trailer
|
||||||
|
<</ID [<216b46f23ae9d6b57462e9f47fac0cc5><216b46f23ae9d6b57462e9f47fac0cc5>]/Info 3 0 R/Root 1 0 R/Size 8>>
|
||||||
|
%iText-Core-7.2.4
|
||||||
|
startxref
|
||||||
|
1662
|
||||||
|
%%EOF
|
Binary file not shown.
|
@ -37,6 +37,18 @@
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itext7-core</artifactId>
|
||||||
|
<version>7.2.4</version>
|
||||||
|
<type>pom</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.23.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
package com.baeldung.iTextPDF;
|
||||||
|
|
||||||
|
import static com.itextpdf.layout.properties.TextAlignment.CENTER;
|
||||||
|
import static com.itextpdf.layout.properties.VerticalAlignment.TOP;
|
||||||
|
import static java.lang.Math.PI;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.itextpdf.io.font.constants.StandardFonts;
|
||||||
|
import com.itextpdf.kernel.font.PdfFont;
|
||||||
|
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||||
|
import com.itextpdf.kernel.geom.PageSize;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfPage;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfReader;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
|
||||||
|
import com.itextpdf.kernel.pdf.extgstate.PdfExtGState;
|
||||||
|
import com.itextpdf.layout.Document;
|
||||||
|
import com.itextpdf.layout.element.Paragraph;
|
||||||
|
import com.itextpdf.layout.element.Text;
|
||||||
|
|
||||||
|
public class StoryTime {
|
||||||
|
|
||||||
|
public static final String OUTPUT_FILE = "output/aliceupdated.pdf";
|
||||||
|
|
||||||
|
public String alice = " Alice was a curious young girl who one day stumbled upon a strange, talking rabbit." + " The rabbit, in a hurry, invited Alice to follow him down a rabbit hole."
|
||||||
|
+ "Alice, not one to turn down an adventure, eagerly followed the rabbit and found herself tumbling down a long, dark tunnel.As she fell, Alice passed through a small door and into a fantastical world filled with talking animals and peculiar characters."
|
||||||
|
+ "She met the Cheshire Cat, who seemed to appear and disappear at will, and the Mad Hatter, who invited her to a tea party."
|
||||||
|
+ "Alice also encountered the tyrannical Queen of Hearts, who was quick to anger and ordered the beheading of anyone who crossed her."
|
||||||
|
+ "Despite the dangers, Alice remained determined to find her way home and eventually stumbled upon the key to the door that would take her back to the real world."
|
||||||
|
+ " As Alice stepped through the door and back into reality, she couldn't help but wonder if it had all been a dream. But the memories of her adventures in Wonderland stayed with her forever, and she often found herself longing to return to that strange and magical place.";
|
||||||
|
|
||||||
|
public String paul = " Paulinho is a Brazilian professional footballer who currently plays as a midfielder for Guangzhou Evergrande Taobao in the Chinese Super League."
|
||||||
|
+ "He has also played for several top clubs around the world, including Barcelona, Tottenham Hotspur, and Guangzhou Evergrande. Paulinho has represented Brazil at the international level and has won several accolades throughout his career, including the Copa America and the Chinese Super League title."
|
||||||
|
+ "He is known for his strong work ethic and powerful offensive play.";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
File file = new File(OUTPUT_FILE);
|
||||||
|
file.getParentFile()
|
||||||
|
.mkdirs();
|
||||||
|
|
||||||
|
// new StoryTime().createPdf();
|
||||||
|
new StoryTime().addWatermarkToExistingPdf();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createPdf() throws IOException {
|
||||||
|
StoryTime storyTime = new StoryTime();
|
||||||
|
String waterMark = "CONFIDENTIAL";
|
||||||
|
PdfWriter writer = new PdfWriter(storyTime.OUTPUT_FILE);
|
||||||
|
PdfDocument pdf = new PdfDocument(writer);
|
||||||
|
|
||||||
|
try (Document document = new Document(pdf)) {
|
||||||
|
|
||||||
|
document.add(new Paragraph(storyTime.alice).setFont(PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN)));
|
||||||
|
document.add(new Paragraph(storyTime.paul));
|
||||||
|
|
||||||
|
Paragraph paragraph = storyTime.createWatermarkParagraph(waterMark);
|
||||||
|
for (int i = 1; i <= document.getPdfDocument()
|
||||||
|
.getNumberOfPages(); i++) {
|
||||||
|
|
||||||
|
storyTime.addWatermarkToPage(document, i, paragraph, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWatermarkToExistingPdf() throws IOException {
|
||||||
|
StoryTime storyTime = new StoryTime();
|
||||||
|
String outputPdf = "output/aliceupdated.pdf";
|
||||||
|
String watermark = "CONFIDENTIAL";
|
||||||
|
|
||||||
|
try (PdfDocument pdfDocument = new PdfDocument(new PdfReader("output/alicepaulwithoutwatermark.pdf"), new PdfWriter(outputPdf))) {
|
||||||
|
Document document = new Document(pdfDocument);
|
||||||
|
|
||||||
|
Paragraph paragraph = storyTime.createWatermarkParagraph(watermark);
|
||||||
|
PdfExtGState transparentGraphicState = new PdfExtGState().setFillOpacity(0.5f);
|
||||||
|
for (int i = 1; i <= document.getPdfDocument()
|
||||||
|
.getNumberOfPages(); i++) {
|
||||||
|
storyTime.addWatermarkToExistingPage(document, i, paragraph, transparentGraphicState, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Paragraph createWatermarkParagraph(String watermark) throws IOException {
|
||||||
|
PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA);
|
||||||
|
Text text = new Text(watermark);
|
||||||
|
text.setFont(font);
|
||||||
|
text.setFontSize(56);
|
||||||
|
text.setOpacity(0.5f);
|
||||||
|
|
||||||
|
return new Paragraph(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWatermarkToPage(Document document, int pageIndex, Paragraph paragraph, float verticalOffset) {
|
||||||
|
PdfPage pdfPage = document.getPdfDocument()
|
||||||
|
.getPage(pageIndex);
|
||||||
|
PageSize pageSize = (PageSize) pdfPage.getPageSizeWithRotation();
|
||||||
|
|
||||||
|
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
|
||||||
|
float y = (pageSize.getTop() + pageSize.getBottom()) / 2;
|
||||||
|
float xOffset = 100f / 2;
|
||||||
|
float rotationInRadians = (float) (PI / 180 * 45f);
|
||||||
|
document.showTextAligned(paragraph, x - xOffset, y + verticalOffset, pageIndex, CENTER, TOP, rotationInRadians);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWatermarkToExistingPage(Document document, int pageIndex, Paragraph paragraph, PdfExtGState graphicState, float verticalOffset) {
|
||||||
|
PdfDocument pdfDoc = document.getPdfDocument();
|
||||||
|
PdfPage pdfPage = pdfDoc.getPage(pageIndex);
|
||||||
|
PageSize pageSize = (PageSize) pdfPage.getPageSizeWithRotation();
|
||||||
|
|
||||||
|
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
|
||||||
|
float y = (pageSize.getTop() + pageSize.getBottom()) / 2;
|
||||||
|
PdfCanvas over = new PdfCanvas(pdfDoc.getPage(pageIndex));
|
||||||
|
over.saveState();
|
||||||
|
over.setExtGState(graphicState);
|
||||||
|
float xOffset = 100f / 2;
|
||||||
|
float rotationInRadians = (float) (PI / 180 * 45f);
|
||||||
|
document.showTextAligned(paragraph, x - xOffset, y + verticalOffset, pageIndex, CENTER, TOP, rotationInRadians);
|
||||||
|
document.flush();
|
||||||
|
over.restoreState();
|
||||||
|
over.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.iTextPDFTest;
|
||||||
|
|
||||||
|
import static com.itextpdf.kernel.pdf.canvas.parser.PdfTextExtractor.getTextFromPage;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.iTextPDF.StoryTime;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfReader;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.kernel.pdf.canvas.parser.listener.LocationTextExtractionStrategy;
|
||||||
|
import com.itextpdf.kernel.pdf.extgstate.PdfExtGState;
|
||||||
|
import com.itextpdf.layout.Document;
|
||||||
|
import com.itextpdf.layout.element.Paragraph;
|
||||||
|
|
||||||
|
class AddWaterMarkToExistingPdfUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAnExistingPDF_whenManipulatedPDFWithIText_thenGeneratePDFwithWatermarks() throws IOException {
|
||||||
|
StoryTime storyTime = new StoryTime();
|
||||||
|
String outputPdf = "output/aliceupdated.pdf";
|
||||||
|
String watermark = "CONFIDENTIAL";
|
||||||
|
|
||||||
|
LocationTextExtractionStrategy extStrategy = new LocationTextExtractionStrategy();
|
||||||
|
try (PdfDocument pdfDocument = new PdfDocument(new PdfReader(outputPdf))) {
|
||||||
|
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
|
||||||
|
String textFromPage = getTextFromPage(pdfDocument.getPage(i), extStrategy);
|
||||||
|
assertThat(textFromPage).contains(watermark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.iTextPDFTest;
|
||||||
|
|
||||||
|
import static com.itextpdf.kernel.pdf.canvas.parser.PdfTextExtractor.getTextFromPage;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.iTextPDF.StoryTime;
|
||||||
|
import com.itextpdf.io.font.constants.StandardFonts;
|
||||||
|
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfReader;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.kernel.pdf.canvas.parser.listener.LocationTextExtractionStrategy;
|
||||||
|
import com.itextpdf.layout.Document;
|
||||||
|
import com.itextpdf.layout.element.Paragraph;
|
||||||
|
|
||||||
|
class GenerateNewPdfWithWatermarkUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNewTexts_whenGeneratingNewPDFWithIText_thenGeneratePDFwithWatermarks() throws IOException {
|
||||||
|
StoryTime storyTime = new StoryTime();
|
||||||
|
String waterMark = "CONFIDENTIAL";
|
||||||
|
|
||||||
|
LocationTextExtractionStrategy extStrategy = new LocationTextExtractionStrategy();
|
||||||
|
try (PdfDocument pdfDocument = new PdfDocument(new PdfReader(storyTime.OUTPUT_FILE))) {
|
||||||
|
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
|
||||||
|
String textFromPage = getTextFromPage(pdfDocument.getPage(i), extStrategy);
|
||||||
|
assertThat(textFromPage).contains(waterMark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue