给文件加水印(Word、PDF)并压缩

给文件加水印(Word、PDF)并压缩

word分为doc文件和docx文件。HWPFDocument是用来操作doc文件的;XWPFDocument 是用来操作docx的。
由于当时无法创建HWPFDocument 对象,所以如果是doc文件的话会转换成docx然后再加水印。

	@ApiOperation(value = "下载附件", notes = "下载附件")
    @PostMapping("/download")
    @ResponseBody
    public ResponseEntity<FileSystemResource> download(@RequestBody NonLitigationVO nonLitigationVO, HttpServletResponse response) throws IOException, XmlException {

        if (nonLitigationVO!=null&&nonLitigationVO.getAnnexId()!=null){
            String annexId = nonLitigationVO.getAnnexId();
            String[] split = annexId.split(",");
            List<Attachment> attachments = attachmentMapper.selectByAttachmentIds(split);
            if (attachments!=null&&attachments.size()>0){
            	//设置压缩路径f
                String f =attachmentConfig.getPath()+"FS"+DateUtils.dateTimeNow("yyyyMMddHHmmss")+RandomUtil.randomNumbers(4)+"/";//DB adress
                File file = new File(f);
                //创建文件夹
                boolean mkdirs = file.mkdirs();
                for (Attachment attachment : attachments) {
                // 给文件加水印 
                WatermarkUtil.addWatermark(new File(attachmentConfig.getPath() + attachment.getAttachmentAddress()),f); }
                int length = file.listFiles().length;
				//打包
                File zip = ZipUtil.zip(f);
                //导出
                return export(zip);
            }}
        return null;
    }
  
    

工具类

package com.boot.reservation.util;


import com.aspose.words.SaveFormat;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.ss.usermodel.*;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.util.List;
import java.util.regex.Pattern;

import static com.boot.reservation.util.ExcelToPDFUtils.getLicense;

public class WatermarkUtil {

    private static final String WATERMARK = "泰裤辣!!!!";

    public static void addWatermark(File file,String folder) throws IOException, XmlException {

        String extension = getFileExtension(file);
        switch (extension) {
            case "doc":
                handlerByDocFile(file,folder);
                break;
            case "docx":
                waterMark2Word(file,folder);
                break;
            case "pdf":
                addWatermarkToPDF(file,folder);
                break;
            default:
                System.out.println("Unsupported file format");
        }
    }

    private static String getFileExtension(File file) {
        String name = file.getName();
        int lastIndexOf = name.lastIndexOf(".");
        if (lastIndexOf == -1) {
            return "";
        }
        return name.substring(lastIndexOf + 1);
    }


    public static void waterMark2Word(File file,String folder) throws IOException {
      //  if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
      //      return;
     //   }
        String path =file.getPath();
        String name =file.getName();
        String modelPath = folder+name;//设置需要加水印的文件路径
        //输入的docx文档
        try{
            InputStream in = new FileInputStream(new File(path));
            XWPFDocument doc= new XWPFDocument(in);
            XWPFParagraph paragraph = doc.createParagraph();//创建文本段落
//        XWPFRun run=paragraph.createRun();//创建run元素
//        run.setText("The Body:");//可以给run元素里写正文内容
            XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();//获取页面页脚
            if (headerFooterPolicy == null) {
                headerFooterPolicy = doc.createHeaderFooterPolicy();//如果没有页眉页脚则创建
            }
            headerFooterPolicy.createWatermark(WATERMARK);//设置水印显示的内容
            XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
            paragraph = header.getParagraphArray(0);
            org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
                    new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
            if (xmlobjects.length > 0) {
                com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape)xmlobjects[0];
                ctshape.setFillcolor("#d8d8d8");//设置水印的颜色
                ctshape.setStyle(ctshape.getStyle() + ";rotation:45");//设置水印的样式  获取默认样式和旋315度
                ctshape.setStyle(getWaterMarkStyle(ctshape.getStyle(),100)  + ";rotation:315");//设置自定义水印的样式,setStyle()方法中需传入样式字符串
            }
            FileOutputStream fileOutputStream = new FileOutputStream(modelPath);
            doc.write(fileOutputStream);
            doc.close();
        }catch (Exception e){
            handlerByDocFile(file,folder);
        }

    }

    /**
     * @param
     * @param
     */
    //pdf格式 动态 xy坐标轴 斜体居中
    public static void addWatermarkToPDF(File file,String folder) {

        try {
            String path = file.getPath();
            String name = file.getName();
            String modelPath = folder+name;
            path = java.net.URLDecoder.decode(path, "utf-8");
            PdfReader reader = new PdfReader(path);
            FileOutputStream fileOutputStream = new FileOutputStream(modelPath);
            PdfStamper stamper = new PdfStamper(reader,fileOutputStream);
            //这里的字体设置比较关键,这个设置是支持中文的写法
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);// 使用系统字体
            int total = reader.getNumberOfPages() + 1;
            PdfContentByte under;
            Rectangle pageRect = null;
            for (int i = 1; i < total; i++) {
                pageRect = stamper.getReader().getPageSizeWithRotation(i);
                // 计算水印X,Y坐标
                float x = pageRect.getWidth() / 2;
                float y = pageRect.getHeight() / 2;
                // 获得PDF最顶层
                under = stamper.getOverContent(i);
                under.saveState();
                // set Transparency
                PdfGState gs = new PdfGState();
                // 设置透明度为0.8
                gs.setFillOpacity(0.6f);
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 100);
                under.setColorFill(BaseColor.GRAY);
                // 水印文字成45度角倾斜
                under.showTextAligned(Element.ALIGN_CENTER, WATERMARK, x, y, 65);
                // 添加水印文字
                under.endText();
                under.setLineWidth(1f);
                under.stroke();
                under.restoreState();
            }
            stamper.close();
            stamper.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }




    
        /**
         * 将水印中的文字替换成传进来的字符串
         * @param graph 要替换的段落
         * @param waterMarkValue 水印文字
         * @throws IOException
         * @throws XmlException
         */
        public static void replaceWaterMark(XWPFParagraph graph,String waterMarkValue) throws IOException, XmlException {
            String paraText = graph.getCTP().xmlText();
            if(paraText.contains("id=\"PowerPlusWaterMarkObject")){//<v:shape id=\"PowerPlusWaterMarkObject
                String beginStr = "string=\"";
                int begin = paraText.indexOf(beginStr) + beginStr.length();
                int end = paraText.indexOf("\"", begin);
                String oldWaterMarkText = paraText.substring(begin, end);
                String newText = paraText.replace("string=\""+ oldWaterMarkText +"\"",
                        "string=\"" + waterMarkValue + "\"");
                XmlToken token = XmlToken.Factory.parse(newText);
                graph.getCTP().set(token);
            }
        }

    /**
     * 设置水印格式
     * word
     *
     * @param styleStr
     * @param height
     * @return
     */
    public static String getWaterMarkStyle(String styleStr, double height) {
        Pattern p = Pattern.compile(";");
        String[] strs = p.split(styleStr);
        for (String str : strs) {
            if (str.startsWith("height:")) {
                String heightStr = "height:" + height + "pt";
                styleStr = styleStr.replace(str, heightStr);
                break;
            }
        }
        return styleStr;
    }


    public static void handlerByDocFile(File file, String folder) throws IOException {

        ByteArrayToFile(convertDocIs2DocxIs( new FileInputStream(new File(file.getPath()))),"cv"+file.getName());
        waterMark2Word(new File("cv"+file.getName()),folder);
    }
    public static void ByteArrayToFile(byte[] data,String newFileNmae) {
        File file = new File(newFileNmae);
        //选择流
        FileOutputStream fos = null;
        ByteArrayInputStream bais = null;
        try {
            bais = new ByteArrayInputStream(data);
            fos = new FileOutputStream(file);
            int temp;
            byte[] bt = new byte[1024*10];
            while((temp = bais.read(bt))!= -1) {
                fos.write(bt,0,temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关流
            try {
                if(null != fos) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 将doc输入流转换为docx输入流
    private static byte[] convertDocIs2DocxIs(InputStream docInputStream) throws IOException {
        byte[] docBytes = FileCopyUtils.copyToByteArray(docInputStream);
        byte[] docxBytes = convertDocStream2docxStream(docBytes);
        return docxBytes;
    }
    // 将doc字节数组转换为docx字节数组
    private static byte[] convertDocStream2docxStream(byte[] arrays) {
        byte[] docxBytes = new byte[1];
        if (arrays != null && arrays.length > 0) {
            try (
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    InputStream sbs = new ByteArrayInputStream(arrays);

            ) {
//                HWPFDocument hwpfDocument = new HWPFDocument(sbs);
//                hwpfDocument.delete(1,70);
                com.aspose.words.Document doc = new com.aspose.words.Document(sbs);
                doc.save(os, SaveFormat.DOCX);
                docxBytes = os.toByteArray();
            } catch (Exception e) {
                System.out.println("出错啦");
            }
        }
        return docxBytes;
    }
}

导出方法

    public ResponseEntity<FileSystemResource> export(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
//        headers.add("url",attachmentConfig.getIp()+attachmentConfig.getPort()+file.getPath());
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }

效果图

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值