首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用iText7 pdfHtml向每个页面添加透明水印文本

如何使用iText7 pdfHtml向每个页面添加透明水印文本
EN

Stack Overflow用户
提问于 2019-03-26 17:52:53
回答 1查看 1.7K关注 0票数 2

目前,我正在尝试添加一个水印,它出现在我的pdf的每一页的背景使用iText7 pdfHtml,但我找不出一个解决方案。例如,我希望文本“机密”出现在每一页的背景中。我尝试用如下的css添加它

代码语言:javascript
运行
复制
@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代码的一个示例:

代码语言:javascript
运行
复制
        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:

代码语言:javascript
运行
复制
<!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:

代码语言:javascript
运行
复制
    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的人!

EN

Stack Overflow用户

回答已采纳

发布于 2019-03-28 03:38:33

这里有一个“在每一页的背景中”添加文本的解决方案。这将在现有内容的后面添加文本,这样就不会掩盖它。请注意,这并没有增加透明度。透明度需要添加外部图形状态。

代码语言:javascript
运行
复制
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();
    }
}

编辑

增加了适用透明度和轮换的第三种选择。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55363450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档