iText自动生成多页PDF时,解决背景(水印)只显示第一页的问题

怎么样自动生成PDF,在我的上一篇博客中有些,这里我主要是记录一下当用itext自动生成PDF文档有多页的的时候,背景(水印)只在第一页显示的问题,这里的背景就是一张已知路径的图片,

下面贴上只有一页有背景图时的部分代码:

Document document = new Document(PageSize.A4);
            // 设置pdf的背景图片
            Image image = Image.getInstance(picPath);//picPath就是背景图片的路径
            image.setAlignment(image.UNDERLYING);
	    // 设置图片在A4的大小填充完全
            image.setAbsolutePosition(0,0);
            image.scaleAbsolute(595,842);
            PdfWriter pdfwriter = PdfWriter.getInstance(document,
                    new FileOutputStream(pdfFile));
            pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);
            document.open();  document.add(image);// 添加图片

我开始是这样写的,然后当PDF文档有多页的时候,背景图片就只有第一页有显示,我去网上找了好久,发现了一种说法是写一个java类,然后继承PdfPageEventHelper,然后自己写方法,这样每次PDF有newPage生成的时候,就会调用大概是这样说的,我当时也是没有看懂,感觉没有说具体,也不说重写什么方法;然后我大概按照他说的方法摸索去试就如下方代码,然后也成功了:

这个是我定义的java类

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;


import java.io.IOException;

public class BackGroundImage extends PdfPageEventHelper {

    private String picPath = "";

    public String getPicPath() {
        return picPath;
    }

    public void setPicPath(String picPath) {
        this.picPath = picPath;
    }

    public BackGroundImage(){

    }

    public BackGroundImage(String path){
        this.picPath = path;
    }

    @Override
    public void onStartPage(PdfWriter pdfWriter, Document document) {
        try {
            Image image = Image.getInstance(picPath);
            image.setAlignment(image.UNDERLYING);
            image.setAbsolutePosition(0,0);
            image.scaleAbsolute(595,842);
            // 设置图片旋转
//            image.setRotation((float) (-Math.PI / 6));
            document.add(image);
        } catch (BadElementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        super.onStartPage(pdfWriter, document);
    }
}
我不知道重写什么方法,我去看父类中有个叫onStartPage方法,翻译过来有点就像新开始页面要执行的,所以试了试,这个新写的类这样引用:

Document document = new Document(PageSize.A4);
            // 设置pdf的背景图片
//            Image image = Image.getInstance(picPath);
//            image.setAlignment(image.UNDERLYING);
//            image.setAbsolutePosition(0,0);
//            image.scaleAbsolute(595,842);

            PdfWriter pdfwriter = PdfWriter.getInstance(document,
                    new FileOutputStream(pdfFile));
            pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);
            pdfwriter.setPageEvent(new BackGroundImage(picPath));
            document.open();
//            document.add(image);

这样我生成的多页PDF就都有背景图片了。

这种是直接把图片作为背景,有一些是直接生成水印而不是图片,下面这段代码也许有点帮助,我改了一下,直接把水印转化为图片保存,也可以直接以流的方式插入,可以自己研究一下,我就直接把生成水印的全部代码粘上了:

(请勿直接复制使用)

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.net.URLDecoder;

/**
 * 添加水印
 */
public class WaterMark {

    /**
     * 通用的水印标注
     *
     * @param request
     * @param response
     * @param billno
     */
    public static String waterMarkStaticDouble(
            HttpServletRequest request, HttpServletResponse response, String billno, boolean dark) {
        String retrunVal = "";
        String fontName = "Arial-Black";
        int fontStyle = 36;
        Color color = new Color(171, 235, 231);
        int fontSize = 78;
        int x = 110;
        int y = -150;
        float alpha = 1.0f;
        int degree = -35;
        String staffId = "java开发交流公司";
        try {
            response.setContentType("image/jpeg");
            String basePath = request.getRealPath("/")
                    .toLowerCase().replaceAll("WEB-INF/classes/".toLowerCase(),
                            "").trim();
            basePath = URLDecoder.decode(basePath.replace("/", "\\"));

            if (basePath.startsWith("\\")) {
                basePath = basePath.substring(1, basePath.length());
            }
            File f = new File(basePath
                    + "WebLibrary\\images\\security_image2.jpg");

//            BufferedImage bgimg = ImageIO.read(f);
            BufferedImage bgimg = new BufferedImage(1000, 520, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bgimg.createGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0,0,1000,520);
            g.dispose();

            BufferedImage currentImg = getText(staffId, bgimg, color, (fontSize - 10), x, y);
            y += (fontSize - 30);
            x += -70;
            currentImg = getText(billno, bgimg, color, (fontSize - 25), x, y);

            y += 320;
            x += -200;
            color = new Color(151, 215, 211);
            currentImg = getText(staffId, bgimg, color, (fontSize - 10), x, y);
            y += (fontSize - 30);
            x += -70;
            currentImg = getText(billno, bgimg, color, (fontSize - 25), x, y);

            currentImg = rotateImg(currentImg, degree, Color.white);
            File folder = new File(basePath+"WebLibrary\\images\\temppic\\");
            if(!folder.exists()){
                folder.mkdirs();
            }
            // 输出到指定的本地路径
            ImageIO.write(currentImg, "jpg", new File(folder+"\\bg"+billno+".jpg"));
            // 返回图片路径
            retrunVal = folder+"\\bg"+billno+".jpg";
        } catch (Exception ex) {
            System.out.println("加水印报错:" + ex.toString());
        }
        return retrunVal;
    }

    /**
     * 艺术字体
     *
     * @param pressText
     * @param image
     * @param color
     * @param fontSize
     * @param x
     * @param y
     * @return
     */
    public static BufferedImage getText(String pressText, BufferedImage image, Color color, int fontSize, int x, int y) {
        Graphics2D g = image.createGraphics();
        java.awt.Font f = new java.awt.Font("楷体", Font.BOLD, fontSize);
        GlyphVector v = f.createGlyphVector(g.getFontMetrics(f).getFontRenderContext(), pressText);
        Shape shape = v.getOutline();
        Rectangle bounds = shape.getBounds();
        g.translate(
                (image.getWidth() - (getLength(pressText) * fontSize)) / 2 + x,
                (image.getHeight() - fontSize) / 2 + y
        );
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.WHITE);
        g.fill(shape);
        g.setColor(color);
        g.setStroke(new BasicStroke(3));//设置粗细
        g.draw(shape);
        return image;
    }

    /**
     * 获取字符串长度
     *
     * @param text
     * @return
     */
    public static int getLength(String text) {
        int length = 0;
        for (int i = 0; i < text.length(); i++) {
            if (new String(text.charAt(i) + "").getBytes().length > 1) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length / 2;
    }

    /**
     * 显示水印的util 开始
     */
    public static BufferedImage rotateImg(BufferedImage image, int degree, Color bgcolor) {

        int iw = image.getWidth();//原始图象的宽度
        int ih = image.getHeight();//原始图象的高度
        int w = 0;
        int h = 0;
        int x = 0;
        int y = 0;
        degree = degree % 360;
        if (degree < 0) degree = 360 + degree;//将角度转换到0-360度之间
        double ang = degree * 0.0174532925;//将角度转为弧度

        /**
         *确定旋转后的图象的高度和宽度
         */

        if (degree == 180 || degree == 0 || degree == 360) {
            w = iw;
            h = ih;
        } else if (degree == 90 || degree == 270) {
            w = ih;
            h = iw;
        } else {
            int d = iw + ih;
            w = (int) (d * Math.abs(Math.cos(ang)));
            h = (int) (d * Math.abs(Math.sin(ang)));
        }

        x = (w / 2) - (iw / 2);//确定原点坐标
        y = (h / 2) - (ih / 2);
        BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
        Graphics gs = rotatedImage.getGraphics();
        gs.setColor(bgcolor);
        gs.fillRect(0, 0, w, h);//以给定颜色绘制旋转后图片的背景
        AffineTransform at = new AffineTransform();
        at.rotate(ang, w / 2, h / 2);//旋转图象
        at.translate(x, y);
        AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        op.filter(image, rotatedImage);
        image = rotatedImage;
        return image;
    }
}



 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值