office文件加水印(可重复)

doc/docx水印实现

import com.spire.doc.*;
import com.spire.doc.documents.WatermarkLayout;

import java.awt.*;
import java.io.File;

public class DocWatermarkServiceImpl implements OfficeWatermarkService {
    @Override
    public void saveWatermark(File file, String watermarkText,String imgPath,Boolean flag) {
        //加载测试文档
        Document document = new Document();

        document.loadFromFile(file.getPath());
        document.setWatermark(null);
        //这里指定目录下的word文档
        //插入文本水印
        InsertTextWatermark(document.getSections().get(0), watermarkText,imgPath,flag);
        file.delete();
        //保存文档
        if(file.getPath().endsWith(".docx")) {
            document.saveToFile(file.getPath(), FileFormat.Docx);
        }else {
            document.saveToFile(file.getPath(), FileFormat.Doc);
        }
    }

    //自定义方法指定文本水印字样,并设置成水印
    private static void InsertTextWatermark(Section section, String watermarkText,String imgPath,Boolean flag) {
        PictureWatermark pictureWatermark = new PictureWatermark();
        pictureWatermark.setPicture(imgPath);

        TextWatermark txtWatermark = new TextWatermark();
        txtWatermark.setText(watermarkText);
        txtWatermark.setFontSize(40);
        txtWatermark.setColor(Color.red);
        txtWatermark.setLayout(WatermarkLayout.Diagonal);
        if(flag){
            section.getDocument().setWatermark(pictureWatermark);
        }else {
            section.getDocument().setWatermark(txtWatermark);
        }

    }
}

xls和xlsx

  /**
     * xlsx 类型添加水印
     *
     * @param inputFilePath
     * @param text
     * @return
     */
    public static void excelWaterMarkForXlsx(String inputFilePath, String text, String imgPath, Boolean flag) {
        FileInputStream is = null;
        FileOutputStream out = null;
        XSSFWorkbook workbook = null;
        ByteArrayOutputStream os = null;
        BufferedImage image = new BufferedImage(200, 400, BufferedImage.TYPE_INT_RGB);
        ;
        try {
            //生成水印图片并导出字节流
            if (flag) {
                File img = new File(imgPath);
                BufferedImage bufferedResizedImage = ImageIO.read(img);

                Image resizedImage = bufferedResizedImage.getScaledInstance(200, 400, Image.SCALE_SMOOTH);
                image = new BufferedImage(200, 400, BufferedImage.TYPE_INT_RGB);
                image.getGraphics().drawImage(resizedImage, 0, 0, null);

            } else {
                image = FontImageUtil.createWatermarkImage(new FontImageUtil.Watermark(true, text, null, null));
            }
            os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            //获取excel工作簿
            is = new FileInputStream(inputFilePath);
            workbook = new XSSFWorkbook(is);
            int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
            POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
            //获取每个Sheet表并插入水印
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                XSSFSheet sheet1 = workbook.getSheetAt(i);

                PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();
                String relType = XSSFRelation.IMAGES.getRelation();
                //add relation from sheet to the picture data
                PackageRelationship pr = sheet1.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
                //set background picture to sheet
                if (sheet1.getCTWorksheet() != null) {
                    sheet1.getCTWorksheet().unsetPicture();
                }
                sheet1.getCTWorksheet().addNewPicture().setId(pr.getId());

            }
            //生成添加水印的excel文件
            File f = new File(inputFilePath);
            f.delete();
            out = new FileOutputStream(inputFilePath);
            workbook.write(out);
        } catch (Exception e) {
            logger.error("excel文件添加水印异常", e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    logger.error("excel输入文件关闭异常", e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    logger.error("excel输出文件关闭异常", e);
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (Exception e) {
                    logger.error("excel工作簿关闭异常", e);
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    logger.error("水印图片字节流关闭异常", e);
                }
            }
        }
    }

    /**
     * xls 类型添加水印
     *
     * @param inputFilePath
     * @param text
     * @return
     */
    public static void excelWaterMarkForXls(String inputFilePath, String text, String imgPath, Boolean flag) {
        FileInputStream is = null;
        FileOutputStream out = null;
        HSSFWorkbook workbook = null;
        ByteArrayOutputStream os = null;
        BufferedImage image = null;
        //水印图片
        String tarImgPath = "";
        try {
            //生成水印图片并导出字节流
            if (flag) {
                File img = new File(imgPath);
                BufferedImage bufferedResizedImage = ImageIO.read(img);

                Image resizedImage = bufferedResizedImage.getScaledInstance(200, 400, Image.SCALE_SMOOTH);
                image = new BufferedImage(200, 400, BufferedImage.TYPE_INT_RGB);
                image.getGraphics().drawImage(resizedImage, 0, 0, null);
                tarImgPath = imgPath;
            } else {
                image = FontImageUtil.createWatermarkImage(new FontImageUtil.Watermark(true, text, null, null));
                File f1 = new File(inputFilePath);
                tarImgPath = f1.getParent() + File.separator + System.nanoTime() + text + ".png";
            }
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(image, "png", outImgStream);
            //获取excel工作簿
            is = new FileInputStream(inputFilePath);
            workbook = new HSSFWorkbook(is);
            byte[] data = getBackgroundBitmapData(tarImgPath); //PNG must not have transparency
            for (int k = 0; k < workbook.getNumberOfSheets(); k++) {
                HSSFSheet sheet1 = workbook.getSheetAt(k);
                Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
                _sheet.setAccessible(true);
                InternalSheet internalsheet = (InternalSheet) _sheet.get(sheet1);
                // get List of RecordBase
                Field _records = InternalSheet.class.getDeclaredField("_records");
                _records.setAccessible(true);
                @SuppressWarnings("unchecked")
                List<RecordBase> records = (List<RecordBase>) _records.get(internalsheet);
                // do creating BitmapRecord and ContinueRecords from the data in parts of 8220 bytes
                BitmapRecord bitmapRecord;
                List<ContinueRecord> continueRecords = new ArrayList<>();
                int bytes;
                if (data.length > 8220) {
                    bitmapRecord = new BitmapRecord(Arrays.copyOfRange(data, 0, 8220));
                    bytes = 8220;
                    while (bytes < data.length) {
                        if ((bytes + 8220) < data.length) {
                            continueRecords.add(new ContinueRecord(Arrays.copyOfRange(data, bytes, bytes + 8220)));
                            bytes += 8220;
                        } else {
                            continueRecords.add(new ContinueRecord(Arrays.copyOfRange(data, bytes, data.length)));
                            break;
                        }
                    }
                } else {
                    bitmapRecord = new BitmapRecord(data);
                }
                int i = 0;
                for (RecordBase r : records) {
                    if (r instanceof org.apache.poi.hssf.record.aggregates.PageSettingsBlock) {
                        break;
                    }
                    i++;
                }
                records.add(++i, bitmapRecord);
                for (ContinueRecord continueRecord : continueRecords) {
                    records.add(++i, continueRecord);
                }

            }
            //生成添加水印的excel文件
            File f = new File(inputFilePath);
            f.delete();
            String outputFilePath = f.getParent() + File.separator + System.currentTimeMillis() + f.getName();
            out = new FileOutputStream(inputFilePath);
            logger.info(outputFilePath);
            outImgStream.close();
            //boolean res = new File(tarImgPath).delete();
            workbook.write(out);
        } catch (Exception e) {
            logger.error("excel文件添加水印异常", e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    logger.error("excel输入文件关闭异常", e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    logger.error("excel输出文件关闭异常", e);
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (Exception e) {
                    logger.error("excel工作簿关闭异常", e);
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    logger.error("水印图片字节流关闭异常", e);
                }
            }

            new File(tarImgPath).delete();

        }
    }


    static byte[] getBackgroundBitmapData(String filePath) throws Exception {

        //see https://www.openoffice.org/sc/excelfileformat.pdf - BITMAP

        // get file byte data in type BufferedImage.TYPE_3BYTE_BGR
        FileInputStream fio = new FileInputStream(filePath);
        BufferedImage in = ImageIO.read(fio);
        BufferedImage image = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        Graphics2D graphics = image.createGraphics();
        graphics.drawImage(in, null, 0, 0);
        graphics.dispose();

        // calculate row size (c)
        int rowSize = ((24 * image.getWidth() + 31) / 32) * 4;

        ByteArrayOutputStream output = new ByteArrayOutputStream(image.getHeight() * rowSize * 3 + 1024);

        // put the record headers into the data
        ByteBuffer header = ByteBuffer.allocate(8 + 12);
        header.order(ByteOrder.LITTLE_ENDIAN);

        // Undocumented XLS stuff
        header.putShort((short) 0x09);
        header.putShort((short) 0x01);
        header.putInt(image.getHeight() * rowSize + 12); // Size of image stream

        // BITMAPCOREHEADER (a)
        header.putInt(12);

        header.putShort((short) image.getWidth());
        header.putShort((short) image.getHeight()); // Use -height if writing top-down

        header.putShort((short) 1); // planes, always 1
        header.putShort((short) 24); // bitcount

        output.write(header.array());

        // Output rows bottom-up (b)
        Raster raster = image.getRaster()
                .createChild(0, 0, image.getWidth(), image.getHeight(), 0, 0, new int[]{2, 1, 0}); // Reverse BGR -> RGB (d)
        byte[] row = new byte[rowSize]; // padded (c)

        for (int i = image.getHeight() - 1; i >= 0; i--) {
            row = (byte[]) raster.getDataElements(0, i, image.getWidth(), 1, row);
            output.write(row);
        }
        fio.close();

        return output.toByteArray();
    }

pdf水印

   /**
     * PDF添加文字水印
     *
     * @param srcPdf   上传文件
     * @param logoText 水印文字
     */
    public static MultipartFile setWaterMarkToPdfByWords(MultipartFile srcPdf, String logoText) {
        try {
            InputStream inputStream = srcPdf.getInputStream();
            PdfDocument pdf = new PdfDocument();
            //加载示例文档
            pdf.loadFromStream(inputStream);
            //true防止中文乱码
            PdfTrueTypeFont pdfTrueTypeFont = new PdfTrueTypeFont(new Font("黑体", Font.BOLD, 55), true);
            BufferedImage image;
            for (int i = 0; i < pdf.getPages().getCount(); i++) {

                //当前页
                PdfPageBase page = pdf.getPages().get(i);

                double width = page.getCanvas().getClientSize().getWidth();
                double height = page.getCanvas().getClientSize().getHeight();
                //1、当前页进行区域划分,当前页纵向3列,横向3行,共9个区域
                Dimension2D dimension2D = new Dimension();
                dimension2D.setSize(width, height);
                //2、对区域画水印
                PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
                //透明度
                brush.getGraphics().setTransparency(ALPHA);
                //旋转角度
                brush.getGraphics().rotateTransform(DEGREE);
                //设置区域水印位置,垂直水平居中
                double offsetX = 0;
                double offsetY = brush.getSize().getHeight() / 2;
                brush.getGraphics().translateTransform(offsetX, offsetY);
                //画水印,居中展示:文本、字体、颜色、x、y、居中展示
                brush.getGraphics().drawString(logoText, pdfTrueTypeFont, PdfBrushes.getCadetBlue(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
                //恢复
                brush.getGraphics().restore();
                //保存格式
                brush.getGraphics().save();
                //3、根据当前页大小,创建新画布
                Rectangle2D loRect = new Rectangle2D.Float();
                loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
                //4、将新画布和水印画入当前页
                page.getCanvas().drawRectangle(brush, loRect);
            }
            //设置缓存区
            pdf.saveToFile(OUT_PATH + srcPdf.getOriginalFilename());
            pdf.close();
            //读取缓存区的文件
            srcPdf = fileToMultipart(OUT_PATH + srcPdf.getOriginalFilename());
        } catch (Exception e) {
            logger.info("pdf添加水印异常: " + e);
            e.printStackTrace();
        }
        return srcPdf;
    }

    /**
     * pdf图片水印
     *
     * @param path
     * @param imgPath
     */
    public static void pdfSavePic(File path,String imgPath){
        PdfDocument pdf = new PdfDocument();
        //载入PDF文档
        pdf.loadFromFile(path.getPath());
        //载入图片
        PdfImage image = PdfImage.fromFile(imgPath);
        //获取图片的宽度和高度用于计算插入水印的初始坐标
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        //循环遍历所有页面以插入水印
        for (int i = 0; i < pdf.getPages().getCount(); i++) {
            //获取一个页面
            PdfPageBase page = pdf.getPages().get(i);
            //获取该页面的宽度和高度,用于计算插入水印的初始坐标
            float pageWidth = (float) (page.getActualSize().getWidth());
            float pageHeight = (float) (page.getActualSize().getHeight());
            //设置水印图片的透明度
            page.getCanvas().setTransparency(0.3f);
            //在页面的中间位置绘制水印图片
            page.getCanvas().drawImage(image, pageWidth/2 - imageWidth/2, pageHeight/2 - imageHeight/2, imageWidth, imageHeight);
        }
        path.delete();
        //保存文档
        pdf.saveToFile(path.getPath());
    }

ppt/pptx实现水印

 public static void excelWaterMarkForPPTx(File file, String text, String imgPath, Boolean flag) {
        String inputFilePath = file.getPath();
        FileInputStream is = null;
        FileOutputStream out = null;
        XMLSlideShow ppt = null;
        ByteArrayOutputStream os = null;
        BufferedImage image = null;
        try {
            // 生成水印图片并导出字节流
            if (flag) {
                File img = new File(imgPath);
                image = ImageIO.read(img);
            } else {
                image = FontImageUtil.createWatermarkImage(new FontImageUtil.Watermark(true, text, null, null));
            }

            os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);

            // 获取 PowerPoint 文件
            is = new FileInputStream(inputFilePath);
            ppt = new XMLSlideShow(is);
            List<XSLFPictureData> pictureData = ppt.getPictureData();
            List<XSLFPictureData> pictureDataList = new ArrayList<XSLFPictureData>() {{
                addAll(pictureData);
            }};
            int size = pictureData.size();

            XSLFPictureData picData = ppt.addPicture(os.toByteArray(), PictureData.PictureType.PNG);
            // 遍历每一页并插入水印
            for (XSLFSlide slide : ppt.getSlides()) {
                if (size != 0) {
                    if (pictureDataList.contains(picData)) {
                        return;
                    } else {
                        XSLFPictureShape pic = slide.createPicture(picData);
                        // 设置图片位置和大小
                        pic.setAnchor(new Rectangle2D.Double(0, 0, picData.getImageDimension().getWidth(), picData.getImageDimension().getHeight()));
                        //pictureData.removeAll(pictureDataList);

                    }
                } else {
                    XSLFPictureShape pic = slide.createPicture(picData);
                    // 设置图片位置和大小
                    pic.setAnchor(new Rectangle2D.Double(0, 0, picData.getImageDimension().getWidth(), picData.getImageDimension().getHeight()));
                }
            }

            // 生成带水印的 PowerPoint 文件
            String tempFilePath = inputFilePath + "temp";
            out = new FileOutputStream(tempFilePath);
            ppt.write(out);

            // 关闭并删除原始文件
            ppt.close();
            is.close();
            out.close();
            File originalFile = new File(inputFilePath);
            originalFile.delete();

            // 重命名临时文件为原始文件
            File tempFile = new File(tempFilePath);
            tempFile.renameTo(originalFile);
        } catch (Exception e) {
            logger.error("PowerPoint 文件添加水印异常", e);
        } finally {
            // 关闭资源
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                logger.error("PowerPoint 输入文件关闭异常", e);
            }
            try {
                if (out != null) out.close();
            } catch (IOException e) {
                logger.error("PowerPoint 输出文件关闭异常", e);
            }
            try {
                if (ppt != null) ppt.close();
            } catch (IOException e) {
                logger.error("PowerPoint 关闭异常", e);
            }
            try {
                if (os != null) os.close();
            } catch (IOException e) {
                logger.error("水印图片字节流关闭异常", e);
            }
        }
    }

    public static void excelWaterMarkForPPT(File file, String text, String imgPath, Boolean flag) {
        String inputFilePath = file.getPath();
        FileInputStream is = null;
        FileOutputStream out = null;
        HSLFSlideShow ppt = null;
        ByteArrayOutputStream os = null;
        BufferedImage image = null;
        try {
            if (flag) {
                File img = new File(imgPath);
                image = ImageIO.read(img);
            } else {
                image = FontImageUtil.createWatermarkImage(new FontImageUtil.Watermark(true, text, null, null));
            }
            // 生成水印图片并导出字节流
            os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);

            // 获取 PowerPoint 文件
            is = new FileInputStream(inputFilePath);
            ppt = new HSLFSlideShow(is);
            HSLFPictureData picData = ppt.addPicture(os.toByteArray(), PictureData.PictureType.PNG);

            // 遍历每一页并插入水印
            for (HSLFSlide slide : ppt.getSlides()) {
                // 创建图片并设置位置
                HSLFPictureShape pic = new HSLFPictureShape(picData);
                pic.setAnchor(new Rectangle2D.Double(0, 0, picData.getImageDimension().getWidth(), picData.getImageDimension().getHeight()));
                slide.addShape(pic);
            }

            // 生成带水印的 PowerPoint 文件
            String tempFilePath = inputFilePath + "temp";
            out = new FileOutputStream(tempFilePath);
            ppt.write(out);

            // 关闭并删除原始文件
            ppt.close();
            is.close();
            out.close();
            File originalFile = new File(inputFilePath);
            originalFile.delete();

            // 重命名临时文件为原始文件
            File tempFile = new File(tempFilePath);
            tempFile.renameTo(originalFile);
        } catch (Exception e) {
            logger.error("PowerPoint 文件添加水印异常", e);
        } finally {
            // 关闭资源
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                logger.error("PowerPoint 输入文件关闭异常", e);
            }
            try {
                if (out != null) out.close();
            } catch (IOException e) {
                logger.error("PowerPoint 输出文件关闭异常", e);
            }
            try {
                if (ppt != null) ppt.close();
            } catch (IOException e) {
                logger.error("PowerPoint 关闭异常", e);
            }
            try {
                if (os != null) os.close();
            } catch (IOException e) {
                logger.error("水印图片字节流关闭异常", e);
            }
        }

    }

在Vue中下载文件水印,可以使用以下步骤: 1. 安装file-saver和xlsx插件,用于文件下载和处理Excel文件。 2. 在Vue组件中定义一个方法,用于下载文件水印。该方法应该包括以下步骤: a. 发送请求获取文件数据。 b. 使用file-saver插件将文件保存到本地。 c. 使用xlsx插件读取Excel文件。 d. 使用canvas在Excel文件上添水印。 e. 将修改后的Excel文件保存到本地。 3. 在Vue组件中定义一个按钮或链接,用于触发下载文件水印的方法。 下面是一个简单的示例代码,用于在Vue中下载Excel文件水印: ``` <template> <div> <button @click="downloadFile">下载文件水印</button> </div> </template> <script> import XLSX from 'xlsx' import FileSaver from 'file-saver' export default { methods: { async downloadFile() { // 发送请求获取文件数据 const response = await fetch('/api/download') const fileData = await response.blob() // 使用file-saver插件将文件保存到本地 FileSaver.saveAs(fileData, 'example.xlsx') // 使用xlsx插件读取Excel文件 const reader = new FileReader() reader.onload = (e) => { const data = new Uint8Array(e.target.result) const workbook = XLSX.read(data, { type: 'array' }) // 使用canvas在Excel文件上添水印 const sheetName = workbook.SheetNames[0] const worksheet = workbook.Sheets[sheetName] const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') const img = new Image() img.src = '/watermark.png' img.onload = () => { canvas.width = img.width canvas.height = img.height ctx.drawImage(img, 0, 0) const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height) // 将水印到Excel文件中 const range = XLSX.utils.decode_range(worksheet['!ref']) for (let row = range.s.r; row <= range.e.r; row++) { for (let col = range.s.c; col <= range.e.c; col++) { const cellAddress = XLSX.utils.encode_cell({ r: row, c: col }) const cell = worksheet[cellAddress] if (cell && cell.v) { const x = col * canvas.width / range.e.c const y = row * canvas.height / range.e.r ctx.putImageData(imageData, x, y) } } } // 将修改后的Excel文件保存到本地 const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }) const blob = new Blob([wbout], { type: 'application/octet-stream' }) FileSaver.saveAs(blob, 'example-watermarked.xlsx') } } reader.readAsArrayBuffer(fileData) } } } </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值