当前,我正在尝试使用iText7 pdfHtml添加出现在pdf每页背景中的水印,但是我无法找到解决方案。例如,我希望文本“机密”出现在每个页面的背景中。我试图像这样用CSS添加它
@page {
size: Letter;
margin: .5in .5in .5in .5in;
@left-middle {
content: "Confidential";
/* z-index: 100; */
font-size: 80pt;
font-weight: bold;
opacity: .2;
text-align: center;
text-transform: uppercase;
transform: translateX(350px) rotate(-54.7deg);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
z-index: 0;
}
}
这几乎解决了我的问题,但是文本不是透明的并且掩盖了其后面的文本。它也不会旋转,但这不是必要条件。
欢迎使用涉及Java,CSS或Html的解决方案。
这是我的Java代码的示例:
FileInputStream htmlStream = null;
FileOutputStream pdfStream = null;
try {
ConverterProperties converterProperties = new ConverterProperties().setBaseUri(path);
converterProperties.setMediaDeviceDescription(new MediaDeviceDescription(MediaType.PRINT));
htmlStream = new FileInputStream(inputPath);
pdfStream = new FileOutputStream(outputPath);
HtmlConverter.convertToPdf(htmlStream, pdfStream, converterProperties);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (htmlStream != null) {
htmlStream.close();
}
if (pdfStream != null) {
pdfStream.close();
}
}
修改
要复制的html示例:
<!DOCTYPE html>
<html>
<link id="watermark_link" href="watermark.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
编辑2
尝试了@BenIngle的答案后,这是我的Java代码,可使其与pdfHtml一起使用:
private static void generatePDFFromHTML(String inputPath, String outputPath, String baseUrl) throws IOException {
FileInputStream htmlStream = null;
FileOutputStream pdfStream = null;
try {
ConverterProperties converterProperties = new ConverterProperties().setBaseUri(baseUrl);
converterProperties.setMediaDeviceDescription(new MediaDeviceDescription(MediaType.PRINT));
htmlStream = new FileInputStream(inputPath);
pdfStream = new FileOutputStream(outputPath);
PdfWriter writer = new PdfWriter(pdfStream);
PdfDocument pdfDocument = new PdfDocument(writer);
Watermark watermark = new Watermark("Confidential");
pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE,watermark);
HtmlConverter.convertToPdf(htmlStream, pdfDocument, converterProperties);
pdfDocument.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (htmlStream != null) {
htmlStream.close();
}
if (pdfStream != null) {
pdfStream.close();
}
}
}
protected static class Watermark implements IEventHandler {
String watermarkText;
public Watermark(String watermarkText) {
this.watermarkText = watermarkText;
}
@Override
public void handleEvent(Event event) {
//Retrieve document and
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), pdf);
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
PdfExtGState gstate = new PdfExtGState();
gstate.setFillOpacity(.2f);
pdfCanvas.setExtGState(gstate);
double rotationDeg = -54.7d;
double rotationRad = Math.toRadians(rotationDeg);
Paragraph watermarkParagraph = new Paragraph(watermarkText)
.setFontSize(80f)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
.setRotationAngle(rotationRad)
.setFixedPosition(100, page.getPageSize().getHeight(), page.getPageSize().getWidth());
canvas.add(watermarkParagraph);
canvas.close();
}
}
我希望这对其他尝试使用iText pdfHtml的人有所帮助!
答案 0 :(得分:0)
这是在“每页背景”中添加文本的解决方案。这将在现有内容后面添加文本,以免掩盖它。请注意,这不会增加透明度。需要在外部图形状态下添加透明度。
try (PdfDocument doc = new PdfDocument(new PdfReader(in.toFile()), new PdfWriter(out.toFile()))) {
PdfFont helvetica = PdfFontFactory.createFont();
for (int pageNum = 1; pageNum <= doc.getNumberOfPages(); pageNum++) {
PdfPage page = doc.getPage(pageNum);
// important - add a new content stream in the beginning, to render behind existing text
PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), doc);
// option 1 - manual placement
canvas.saveState();
canvas.beginText();
canvas.setFillColor(ColorConstants.GRAY);
canvas.setFontAndSize(helvetica, 80f);
canvas.moveText(0f, page.getPageSize().getHeight() - 80f);
canvas.showText("Confidential1");
canvas.endText();
canvas.restoreState();
// option 2 - let iText place it
try (Canvas canvas1 = new Canvas(canvas, doc, page.getPageSize())) {
Paragraph watermark = new Paragraph("Confidential2")
.setFontColor(ColorConstants.GRAY)
.setFont(helvetica)
.setFontSize(80f)
.setHorizontalAlignment(HorizontalAlignment.LEFT)
.setVerticalAlignment(VerticalAlignment.BOTTOM)
.setFixedPosition(0f, page.getPageSize().getHeight() - 100f, page.getPageSize().getWidth());
canvas1.add(watermark);
}
// option 3 - set opacity and place on top of existing content, plus rotation
PdfExtGState gstate = new PdfExtGState();
gstate.setFillOpacity(.2f);
canvas = new PdfCanvas(page);
canvas.saveState();
canvas.setExtGState(gstate);
try (Canvas canvas2 = new Canvas(canvas, doc, page.getPageSize())) {
double rotationDeg = -54.7d;
double rotationRad = Math.toRadians(rotationDeg);
Paragraph watermark = new Paragraph("Confidential3")
.setFont(helvetica)
.setFontSize(80f)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
.setRotationAngle(rotationRad)
.setFixedPosition(100, page.getPageSize().getHeight(), page.getPageSize().getWidth());
canvas2.add(watermark);
}
canvas.restoreState();
}
}
添加了第三个应用透明度和旋转的选项。