目前,我正在尝试添加一个水印,它出现在我的pdf的每一页的背景使用iText7 pdfHtml,但我找不出一个解决方案。例如,我希望文本“机密”出现在每一页的背景中。我尝试用如下的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的人!
发布于 2019-03-28 03:38:33
这里有一个“在每一页的背景中”添加文本的解决方案。这将在现有内容的后面添加文本,这样就不会掩盖它。请注意,这并没有增加透明度。透明度需要添加外部图形状态。
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();
}
}
编辑
增加了适用透明度和轮换的第三种选择。
https://stackoverflow.com/questions/55363450
复制相似问题