java 给图片、word、excel、pdf添加水印

发布于:2024-09-19 ⋅ 阅读:(34) ⋅ 点赞:(0)

话不多说直接上代码

下载simsun.ttc字体

调用方法:downloadFileWater()

html转pdf方法:htmlToPdf()

excel动态导出公共方法:exportColumn(),表设计

create table export(

        id bigint not null auto_increment,

        code varchar(22) default null comment '导出字段code',

        name varchar(225) default null comment '导出字段name',

        sort int default null comment '排名',

)

INSERT INTO export(`id`, `code`, `name`, `sort`) VALUES ('1', 'demandManageId', '需求编码', '1');
INSERT INTO export (`id`, `code`, `name`, `sort`) VALUES ('2', 'demandNumber', '订单号', '2');
INSERT INTO export (`id`, `code`, `name`, `sort`) VALUES ('3', 'statusName', '状态', '3');
INSERT INTO export(`id`, `code`, `name`, `sort`) VALUES ('4', 'demandTypeName', '需求类型', '4');
INSERT INTO export (`id`, `code`, `name`, `sort`) VALUES ('5', 'contactName', '需求联系人', '5');
INSERT INTO export(`id`, `code`, `name`, `sort`) VALUES ('6', 'contactPhone', '联系人电话', '6');
INSERT INTO export(`id`, `code`, `name`, `sort`) VALUES ('7', 'startTime', '执行开始时间', '7');

import cn.com.cgnpc.luin.common.enums.FileMimeTypeEnum;
import cn.com.cgnpc.luin.common.exception.BusinessException;
import cn.com.cgnpc.luin.common.exception.CertificationException;
import cn.com.cgnpc.luin.common.exception.ContractException;
import cn.com.cgnpc.luin.common.exception.HealthException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.*;
import com.microsoft.schemas.office.office.CTLock;
import com.microsoft.schemas.vml.*;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.HeaderFooter;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.ShapeLineStyle;
import com.spire.doc.documents.ShapeType;
import com.spire.doc.fields.ShapeObject;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.http.HttpStatus;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileUtil {
    /** word字体 */
    private static final String FONT_NAME = "宋体";
    /** 字体大小 */
    private static final String FONT_SIZE = "0.2pt";
    /** 字体颜色 */
    private static final String FONT_COLOR = "#d0d0d0";
    /** 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)*/
    private static final Integer WIDTH_PER_WORD = 10;
    /** 与顶部的间距 */
    private static Integer STYLE_TOP = 0;
    /** 文本旋转角度 */
    private static final String STYLE_ROTATION = "30";

    private static final Color COLOR = Color.LIGHT_GRAY;
    // 图片添加水印
    public static File addWatermarkAndCompress(InputStream inputStream, File outputFile,String watermarkText) throws IOException {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(inputStream);
        // 添加水印
        BufferedImage watermarkedImage = addWatermark(originalImage, watermarkText);
        // 获取原图尺寸
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();

        // 使用Thumbnails.of方法对添加水印后的图片进行缩放和压缩
        // 按比例缩放并压缩
        Thumbnails.of(watermarkedImage)
                .size(originalWidth, originalHeight)
                .outputQuality(0.4) // 调整画质压缩
                .toFile(outputFile);

        return outputFile;
    }
public static BufferedImage addWatermark(BufferedImage image, String watermarkText) {
        // 获取原始图片的宽度和高度
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        // 创建用于绘制水印的对象
        Graphics2D g2d = (Graphics2D) image.getGraphics();
        // 设置透明度,使水印呈现半透明效果
        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
        g2d.setComposite(alphaChannel);
        // 设置水印文字颜色为灰色
        g2d.setColor(Color.GRAY);
        // 设置水印文字的字体、大小和样式
        Font font = new Font("SimHei", Font.BOLD, 36);
        g2d.setFont(font);
        // 获取水印文字的尺寸信息
        FontMetrics fontMetrics = g2d.getFontMetrics();
        Rectangle2D rect = fontMetrics.getStringBounds(watermarkText, g2d);
        int textWidth = (int) rect.getWidth();
        // 设置水印倾斜角度
        g2d.rotate(-0.5);
        // 平铺添加水印
        int fontSize = (imageWidth + imageHeight) / 100;
        int split = fontSize * 10;
        int xCanNum = imageWidth/textWidth + 1;
        int yCanNum = imageHeight/fontSize + 1;
        for (int i =1;i<=yCanNum;i++){
            int y = fontSize * i + split * i;
            for (int j =0;j<xCanNum;j++){
                int x=textWidth * j + split * j;
                g2d.drawString(watermarkText,x,y-(fontSize+split)*j);
            }
        }
        // 释放Graphics2D资源
        g2d.dispose();
        // 返回添加了水印的图片
        return image;
    }

    /**
     *
     * @param inputStream 原文件
     * @param outputFile 输出文件
     * @param waterMarkName 水印字
     * @param opacity 水印透明度
     * @param fontsize 字体大小
     * @param angle 水印倾斜度
     * @param heightdensity 数据越大 竖向水印越少
     * @param widthdensity 数据越大 横向水印越少
     * @return File
     */
    public static File pdfWaterMark(InputStream inputStream, File outputFile, String waterMarkName,
                                 float opacity, int fontsize, int angle, int heightdensity, int widthdensity) {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(inputStream);
            stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            com.lowagie.text.Rectangle pageRect;
            PdfGState gs = new PdfGState();
            //这里是透明度设置
            gs.setFillOpacity(opacity);
            //这里是条纹不透明度
            gs.setStrokeOpacity(0.2f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            FontMetrics metrics;
            int textH;
            int textW;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();  //字符串的高,   只和字体有关
            textW = metrics.stringWidth(label.getText());  //字符串的宽
            PdfContentByte under;
            //这个循环是确保每一张PDF都加上水印
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                under = stamper.getOverContent(i);  //在内容上方添加水印
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, fontsize); //这里是水印字体大小
                for (int height =  textH; height < pageRect.getHeight()*2; height = height + textH * heightdensity) {
                    for (int width =  textW; width < pageRect.getWidth()*1.5 + textW; width = width + textW * widthdensity) {
                        under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, angle);
                    }
                }
                //添加水印文字
                under.endText();
            }
            return outputFile;
        } catch (IOException | DocumentException e) {
            log.info("添加水印失败!错误信息为: " , e);
            e.printStackTrace();
        } finally {
            //关闭流
            if (stamper != null) {
                try {
                    stamper.close();
                } catch (DocumentException | IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                reader.close();
            }
        }
        return null;
    }
public static File wordDocWater(InputStream inputStream, File outputFile, String waterMarkName){
        try (OutputStream os = new FileOutputStream(outputFile)){
            Document document = new Document(inputStream);
            Section section ;
            // 添加艺术字并设置大小
            ShapeObject shape = new ShapeObject(document, ShapeType.Text_Plain_Text);
            for (int n = 0; n < document.getSections().getCount(); n++) {
                section = document.getSections().get(n);
                // 获取section的页眉
                HeaderFooter header = section.getHeadersFooters().getHeader();
                Paragraph paragraph;
                if (header.getParagraphs().getCount() > 0) {
                    // 如果页眉有段落,取它第一个段落
                    paragraph = header.getParagraphs().get(0);
                } else {
                    // 否则新增加一个段落到页眉
                    paragraph = header.addParagraph();
                }
                for (int i = 0; i < 4; i++) {// 列
                    for (int j = 0; j < 5; j++) {// 行
                        // 复制艺术字并设置多行多列位置
                        shape = (ShapeObject) shape.deepClone();
                        shape.setWidth(160);// 字体宽度
                        shape.setHeight(10);// 字体高度
                        shape.setRotation(330);// 旋转
                        shape.getWordArt().setFontFamily("宋体");// 水印字体
                        shape.getWordArt().setText(waterMarkName);// 水印
                        shape.setFillColor(new Color(128, 128, 128));// 中心填充颜色
                        shape.setStrokeColor(new Color(204, 204, 204));// 边缘填充颜色
                        shape.setStrokeWeight(0.5);// 字体宽度(<=1)
                        shape.setLineStyle(ShapeLineStyle.Single);// 格式
                        //设置循环次数,几行几列
                        shape.setVerticalPosition( 150 * i);//50代表行的起始位置
                        shape.setHorizontalPosition( 160 * j);//20代表列的起始位置
                        paragraph.getChildObjects().add(shape);
                    }
                }
            }
            //保存文档
            document.saveToFile(os,FileFormat.Auto);
        }catch (Exception e){
            log.info("word doc 添加水印异常: " , e);
        }
        return outputFile;
    }

    /** word docx添加水印
     * @param inputStream 原文件
     * @param outputFile 输出文件
     * @param waterMarkName 水印字
     **/
    public static File wordDocxWater(InputStream inputStream, File outputFile, String waterMarkName) {
        long beginTime = System.currentTimeMillis();

        try (
                OutputStream out = new FileOutputStream(outputFile);
                XWPFDocument doc = new XWPFDocument(inputStream);
        ) {

            // 把整页都打上水印
            for (int lineIndex = -20; lineIndex < 40; lineIndex++) {
                STYLE_TOP = 200 * lineIndex;
                waterMarkDocXDocument(doc, waterMarkName);
            }

            // 输出新文档
            doc.write(out);
            log.info("添加水印成功!,一共耗时" + (System.currentTimeMillis() - beginTime) + "毫秒");

        } catch (IOException e) {
            log.info("docx水印添加失败:",e);
        }
        return outputFile;
    }
    /**
     * 为文档添加水印
     * @param doc        需要被处理的docx文档对象
     * @param fingerText 需要添加的水印文字
     */
    public static void waterMarkDocXDocument(XWPFDocument doc, String fingerText) {
        // 水印文字之间使用8个空格分隔
        fingerText = fingerText + repeatString(" ", 10);
        // 一行水印重复水印文字次数
        fingerText = repeatString(fingerText, 10);
        // 如果之前已经创建过 DEFAULT 的Header,将会复用
        XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
        int size = header.getParagraphs().size();
        if (size == 0) {
            header.createParagraph();
        }
        CTP ctp = header.getParagraphArray(0).getCTP();
        byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();
        byte[] rsidrDefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
        ctp.setRsidP(rsidr);
        ctp.setRsidRDefault(rsidrDefault);
        CTPPr ppr = ctp.addNewPPr();
        ppr.addNewPStyle().setVal("Header");
        // 开始加水印
        CTR ctr = ctp.addNewR();
        CTRPr ctrpr = ctr.addNewRPr();
        ctrpr.addNewNoProof();
        CTGroup group = CTGroup.Factory.newInstance();
        CTShapetype shapeType = group.addNewShapetype();
        CTTextPath shapeTypeTextPath = shapeType.addNewTextpath();
        shapeTypeTextPath.setOn(STTrueFalse.T);
        shapeTypeTextPath.setFitshape(STTrueFalse.T);
        CTLock lock = shapeType.addNewLock();
        lock.setExt(STExt.VIEW);
        CTShape shape = group.addNewShape();
        shape.setId("PowerPlusWaterMarkObject");
        shape.setSpid("_x0000_s102");
        shape.setType("#_x0000_t136");
        // 设置形状样式(旋转,位置,相对路径等参数)
        shape.setStyle(getShapeStyle(fingerText));
        shape.setFillcolor(FONT_COLOR);
        // 字体设置为实心
        shape.setStroked(STTrueFalse.FALSE);
        // 绘制文本的路径
        CTTextPath shapeTextPath = shape.addNewTextpath();
        // 设置文本字体与大小
        shapeTextPath.setStyle("font-family:" + FONT_NAME + ";font-size:" + FONT_SIZE);
        shapeTextPath.setString(fingerText);
        CTPicture pict = ctr.addNewPict();
        pict.set(group);
    }
/**
     * 构建Shape的样式参数
     */
    private static String getShapeStyle(String fingerText) {
        StringBuilder sb = new StringBuilder();
        // 文本path绘制的定位方式
        sb.append("position: ").append("absolute");
        // 计算文本占用的长度(文本总个数*单字长度)
        sb.append(";width: ").append(fingerText.length() * WIDTH_PER_WORD).append("pt");
        // 字体高度
        sb.append(";height: ").append("20pt");
        sb.append(";z-index: ").append("-251654144");
        sb.append(";mso-wrap-edited: ").append("f");
        // 设置水印的间隔,这是一个大坑,不能用top,必须要margin-top。
        sb.append(";margin-top: ").append(STYLE_TOP);
        sb.append(";mso-position-horizontal-relative: ").append("page");
        sb.append(";mso-position-vertical-relative: ").append("page");
        sb.append(";mso-position-vertical: ").append("left");
        sb.append(";mso-position-horizontal: ").append("center");
        sb.append(";rotation: ").append(STYLE_ROTATION);
        return sb.toString();
    }
    /**
     * 将指定的字符串重复repeats次.
     */
    private static String repeatString(String pattern, int repeats) {
        StringBuilder buffer = new StringBuilder(pattern.length() * repeats);
        Stream.generate(() -> pattern).limit(repeats).forEach(buffer::append);
        return new String(buffer);
    }

    /**
     * excel 添加水印
     * @param wb Excel Workbook
     * @param sheet 需要打水印的Excel
     * @param waterRemarkPath
     * @param startXCol 水印起始列
     * @param startYRow 水印起始行
     * @param betweenXCol 水印横向之间间隔多少列
     * @param betweenYRow 水印纵向之间间隔多少行
     * @param XCount 横向共有水印多少个
     * @param YCount 纵向共有水印多少个
     * @param waterRemarkWidth 水印图片宽度为多少列
     * @param waterRemarkHeight 水印图片高度为多少行
     */
    public static void putWaterRemarkToExcel(Workbook wb, Sheet sheet, String waterRemarkPath, int startXCol,
                                             int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
                                             int waterRemarkHeight){
        try{
            // 校验传入的水印图片格式
            if (!waterRemarkPath.endsWith("png") && !waterRemarkPath.endsWith("PNG")) {
                throw new RuntimeException("向Excel上面打印水印,目前支持png格式的图片。");
            }
            // 加载图片
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            InputStream imageIn = new FileInputStream(waterRemarkPath);
            if (imageIn.available() < 1) {
                throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(1)。");
            }
            BufferedImage bufferImg = ImageIO.read(imageIn);
            if (null == bufferImg) {
                throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(2)。");
            }
            ImageIO.write(bufferImg, "png", byteArrayOut);
            // 开始打水印
            Drawing<?> drawing = sheet.createDrawingPatriarch();
            // 按照共需打印多少行水印进行循环
            for (int yCount = 0; yCount < YCount; yCount++) {
                // 按照每行需要打印多少个水印进行循环
                for (int xCount = 0; xCount < XCount; xCount++) {
                    // 创建水印图片位置
                    int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
                    int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
                    /*
                     * 参数定义: 第一个参数是(x轴的开始节点); 第二个参数是(是y轴的开始节点); 第三个参数是(是x轴的结束节点);
                     * 第四个参数是(是y轴的结束节点); 第五个参数是(是从Excel的第几列开始插入图片,从0开始计数);
                     * 第六个参数是(是从excel的第几行开始插入图片,从0开始计数); 第七个参数是(图片宽度,共多少列);
                     * 第8个参数是(图片高度,共多少行);
                     */
                    ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
                            yIndexInteger, xIndexInteger + waterRemarkWidth, yIndexInteger + waterRemarkHeight);
                    Picture pic = drawing.createPicture(anchor,
                            wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
                    pic.resize();
                }

            }
        }catch (Exception e){
            log.info("下载excel添加水印失败:",e);
        }
    }

    /**
     * excel设置水印
     * @param markStr
     */
    public static File setExcelWaterMark(InputStream inputStream, File outFile, String markStr,String fix) throws Exception {
        //读取excel文件
        Workbook wb = null;
        try {
            if("xlsx".equals(fix))
                wb = new XSSFWorkbook(inputStream);
            if("xls".equals(fix))
                wb = new HSSFWorkbook(inputStream);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        //设置水印图片路径
        String realPath = File.separator + "template" + File.separator + UUID.randomUUID().toString().replace("-", "") + ".png";
        //String realPath = "/temp/" + "waterImage" + UUID.randomUUID().toString().replace("-", "") + ".png";
        try {
            createWaterMarkImage(markStr, realPath);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        //获取excel sheet个数
        int sheets = wb.getNumberOfSheets();
        //循环sheet给每个sheet添加水印
        for (int i = 0; i < sheets; i++) {
            Sheet sheet = wb.getSheetAt(i);
            //获取excel实际所占列
            int row = sheet.getFirstRowNum() + sheet.getLastRowNum();
            int cell = 0;
            if(null != sheet.getRow(sheet.getFirstRowNum())) {
                cell = sheet.getRow(sheet.getFirstRowNum()).getLastCellNum() + 1;
            }
            //根据行与列计算实际所需多少水印
            putWaterRemarkToExcel(wb, sheet, realPath, 0, 0, 5, 5, cell / 5 + 1, row / 5 + 1, 0, 0);
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            wb.write(os);
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        // Excel文件生成后存储的位置。

        try(OutputStream fos= new FileOutputStream(outFile)) {
            fos.write(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        File imageTempFile = new File(realPath);
        if(imageTempFile.exists()) {
            imageTempFile.delete();
        }
        return outFile;
    }
    /**
     * 根据文字生成水印图片
     */
    public static void createWaterMarkImage(String content, String path) throws IOException {
        Integer width = 300;
        Integer height = 80;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象
        String fontType = "宋体";
        Integer fontStyle = Font.PLAIN;
        Integer fontSize = 30;
        Font font = new Font(fontType, fontStyle, fontSize);
        Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        g2d.setColor(COLOR); //设置字体颜色和透明度
        g2d.setStroke(new BasicStroke(1)); // 设置字体
        g2d.setFont(font); // 设置字体类型  加粗 大小
        g2d.rotate(Math.toRadians(-10), (double) image.getWidth() / 2, (double) image.getHeight() / 2);//设置倾斜度
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(content, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = -bounds.getY();
        double baseY = y + ascent;
        // 写入水印文字原定高度过小,所以累计写水印,增加高度
        g2d.drawString(content, (int) x, (int) baseY);
        // 设置透明度
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 释放对象
        g2d.dispose();
        ImageIO.write(image, "png", new File(path));
    }

    /**
     * 下载水印文件
     * @param fix 文件名后缀
     * @param is 文件输入流
     * @param outFile 输出文件
     * @param waterText 水印文本
     * @param path 临时文件路径
     * @param response 响应
     */
    public static void downloadFileWater(String fix,InputStream is,File outFile,String waterText,String path,HttpServletResponse response) {
        try {
            // 图片水印
            if(FileUtil.checkImage(fix)){
                addWatermarkAndCompress(is, outFile, waterText);
            }
            // pdf水印
            else if (FileUtil.checkPdf(fix)){
                pdfWaterMark(is, outFile, waterText,
                        0.3f, 20, 30, 10, 2);
            }
            // word水印
            else if(FileUtil.checkWord(fix)){
                if("doc".equals(fix)){
                    wordDocWater(is, outFile, waterText);
                    BufferedOutputStream outputStream = null;
                    try(InputStream ist = new FileInputStream(path);
                        HWPFDocument doc = new HWPFDocument(ist)){
                        int numParagraphs = doc.getRange().numParagraphs();
                        if (numParagraphs > 0){
                            doc.getRange().getParagraph(0).delete();
                        }
                        File file = new File(path);
                        if (file.exists()) {
                            file.delete();
                        }
                        outputStream = new BufferedOutputStream(new FileOutputStream(path));
                        doc.write(outputStream);
                        outputStream.flush();
                        outFile = new File(path);
                    }catch (Exception e){
                        log.info("水印添加失败",e);
                    }finally {
                        try{
                            if(null != outputStream) outputStream.close();
                        }catch (Exception e){
                            log.info("doc关闭流失败",e);
                        }
                    }
                }
                if("docx".equals(fix))
                    wordDocxWater(is, outFile, waterText);
            }
            // excel水印
            else if(FileUtil.checkExcel(fix)){
                setExcelWaterMark(is,outFile,waterText,fix);
            }
            downloadFile(response,outFile);
        } catch (Exception e) {
            log.info("水印文件下载异常:",e);
        }
    }



    /**
     * html转pdf
     * @param bytes 字符串字节
     * @param outFile 输出文件路径
     * @param waterText 水印文字
     * @param response 响应
     */
    public static void htmlToPdf(byte[] bytes,File outFile,String waterText,HttpServletResponse response){
        try {
            // pdf 添加水印
            pdfWaterMark(new ByteArrayInputStream(bytes), outFile, waterText,
                    0.3f, 20, 30, 10, 2);
            // 下载文件
            downloadFile(response,outFile);
        }catch (Exception e){
            log.info("html转pdf失败:",e);
        }
    }

    public static void exportColumn(HttpServletResponse response,List<?> columnList,List<?> dataList,String fileName){
        try{
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet();
            Row titleRow = sheet.createRow(0);
            for (int i=0;i<columnList.size();i++){
                Class<?> columnClazz = columnList.get(i).getClass();
                Field field = columnClazz.getDeclaredField("name");
                ReflectionUtils.makeAccessible(field);
                Cell title = titleRow.createCell(i);
                Object o = field.get(columnList.get(i));
                title.setCellValue(String.valueOf(o));
                // 设置列宽
                sheet.autoSizeColumn(i);
                sheet.setColumnWidth(i,20*256);
            }
            // 填充数据
            for (int i=0;i<dataList.size();i++){
                Row row = sheet.createRow(i+1);
                for (int j=0;j<columnList.size();j++){
                    Class<?> columnClazz = columnList.get(j).getClass();
                    Field field = columnClazz.getDeclaredField("code");
                    ReflectionUtils.makeAccessible(field);
                    Cell cell = row.createCell(j);
                    Object obj = getPropertyValue(dataList.get(i),String.valueOf(field.get(columnList.get(j))));
                    cell.setCellValue(null == obj ? null : String.valueOf(obj));
                }
            }
            // 设置响应头
            response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(fileName,"UTF-8")+".xlsx");
            response.setStatus(HttpServletResponse.SC_OK);
            // 写入响应流
            workbook.write(response.getOutputStream());
            workbook.close();
        }catch (Exception e){
            log.info("e鹭认证导出失败:",e);
            throw new CertificationException("导出失败");
        }
    }
    public static Object getPropertyValue(Object obj, String propertyName) {
        try{
            Class<?> clazz = obj.getClass();
            Field field = clazz.getDeclaredField(propertyName);
            ReflectionUtils.makeAccessible(field);
            return field.get(obj);
        }catch (Exception e){
            log.info("获取属性值失败:",e);
        }
        return null;
    }
	/**
     * 下载文件
     */
    public static void downloadFile(HttpServletResponse response, File file) {
        FileInputStream fis = null;
        try(OutputStream outputStream = response.getOutputStream()) {
            if(null == file){
                throw new HealthException("没找到文件");
            }
            response.setContentType("application/force-download;charset=UTF-8");
            response.setHeader("Content-Disposition", java.net.URLEncoder.encode(file.getName(), "UTF-8"));

            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int len;
            while ((len = fis.read(b)) != -1) {
                outputStream.write(b, 0, len);
            }
        } catch (IOException e) {
            log.error("下载文件失败:{}",e.getMessage());
            throw new HealthException("下载文件失败");
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    log.error("下载文件关闭流失败:{}",e.getMessage());
                }
            }
        }

        if (file.exists()) {
            boolean delete = file.delete();
            log.info("下载文件后删除文件{}",delete);
        }
    }

}


网站公告

今日签到

点亮在社区的每一天
去签到