java 使用aspose,itextpdf文件转pdf;txt、xls、xlsx、ppt、ppts、doc、docx,加上水印

背景:oa系统中的一个模块(类似网盘),需要对在线预览,下载的文件动态加上登录人的信息:用户名、账号、时间、组织;考虑如果按照源文件格式下载,水印无法加入并且,用户有可能修改其它用户分享过来的文件,故考虑转曾pdf 进行下载和预览。

一、样例展示:

贴两张水印后预览和下载的效果图:

二、jar包引入

<dependency>
    <groupId>com.luhuiguo</groupId>
    <artifactId>aspose-words</artifactId>
    <version>22.10</version>
</dependency>
<dependency>
    <groupId>com.luhuiguo</groupId>
    <artifactId>aspose-cells</artifactId>
    <version>22.10</version>
</dependency>
<dependency>
    <groupId>com.luhuiguo</groupId>
    <artifactId>aspose-slides</artifactId>
    <version>23.1</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.1</version>
</dependency>

三、jar包引入的方式

1、使用我本地的jar包,下方有下载

链接: https://pan.baidu.com/s/1wnpUCbPPqEDeR22nVGScdw

提取码: 21sv 复制这段内容后打开百度网盘手机App,操作更方便哦

2、在maven 官网找到需要的jar包版本,通过命令的形式打入本地maven库Maven CentralOfficial search by the maintainers of Maven Central Repository.icon-default.png?t=N7T8https://central.sonatype.com/

打入本地maven仓库的命令可参考这个博主的:

如何将jar加入自己的maven本地仓库_本地jar上传到私有maven仓库-CSDN博客

四、需要配置一个去除水印的license.xml,放在项目中resource目录下

<?xml version="1.0" encoding="UTF-8" ?>
<License>
    <Data>
        <Products>
            <Product>Aspose.Total for Java</Product>
            <Product>Aspose.Words for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
    </Data>
    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

五、代码展现:

package com.zngk.biz.modular.employeesSpace.utils;

import com.aspose.slides.License;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
import lombok.extern.log4j.Log4j2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * ppt转pdf工具类
 */
@Log4j2
public class PptConvertPdfUtil {

    public static boolean getLicense() {
        boolean result = false;
        try {
            //  license.xml应放在.
            InputStream is = ExcelConvertPdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void ppt2Pdf(String inPath,String outPath){
        // 验证License 去除水印
        if (!getLicense()) {
            return ;
        }
        long start = System.currentTimeMillis();
        try {
            //这里是当inPath地址为http开头的
            URL url = new URL(inPath);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();

            //这里是当inPath地址为某个盘
            //FileInputStream fileInput = new FileInputStream(inPath);

            Presentation pres = new Presentation(inputStream);
            FileOutputStream out = new FileOutputStream(new File(outPath));
            pres.save(out, SaveFormat.Pdf);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end =System.currentTimeMillis();
        // 转化用时
        log.info("pdf转换成功,共耗时:{}" , ((end - start) / 1000.0) + "秒");
    }

    public static void main(String[] args) {
        String inPath = "C:/Users/Asus/Desktop/招聘系统搭建.pptx";
        String outPath ="C:/gkzcwebfile/xxx.pdf";
        ppt2Pdf(inPath,outPath);
    }

}
package com.zngk.biz.modular.employeesSpace.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Paragraph;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author YBug
 * @version 1.0
 * @date 2024/3/28 10:58
 * @Describe
 */
public class TxtConvertPdfUtil {

    public static void txt2Pdf(String inputFile,String outputFile){
        try {
            // 创建文档对象
            Document document = new Document();
            // 创建PdfWriter对象
            PdfWriter.getInstance(document, new FileOutputStream(outputFile));
            // 打开文档
            document.open();
            URL url = new URL(inputFile);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();
            // 读取txt文件并写入pdf文件
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                Paragraph paragraph = new Paragraph(line);
                document.add(paragraph);
            }
            // 关闭文档
            document.close();
            System.out.println("文件转换成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        txt2Pdf("地址", "C:/gkzcwebfile/a.pdf");
    }
}
package com.zngk.biz.modular.employeesSpace.utils;

import com.aspose.cells.License;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * excel表格转换pdf
 */
@Log4j2
public class ExcelConvertPdfUtil {

    public static boolean getLicense() {
        boolean result = false;
        try {
            //  license.xml应放在.
            InputStream is = ExcelConvertPdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * excel 转为pdf 输出。
     *
     * @param sourceFilePath  excel文件
     * @param desFilePathd  pad 输出文件目录
     */
    public static void excel2pdf(String sourceFilePath, String desFilePathd){
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            return;
        }
        log.info("开始转换excel==start");
        FileOutputStream fileOS = null;
        long old = System.currentTimeMillis();
        try {
            URL url = new URL(sourceFilePath);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            BufferedInputStream bis = null;
            bis = new BufferedInputStream(connection.getInputStream());
            // 原始excel路径
            Workbook wb = new Workbook(bis);
            fileOS = new FileOutputStream(desFilePathd);
            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
            pdfSaveOptions.setOnePagePerSheet(true);
            int[] autoDrawSheets={3};
            //当excel中对应的sheet页宽度太大时,在PDF中会拆断并分页。此处等比缩放。
            autoDraw(wb,autoDrawSheets);
            int[] showSheets={0};
            //隐藏workbook中不需要的sheet页。
//            printSheetPage(wb,showSheets);
            wb.save(fileOS, pdfSaveOptions);
            fileOS.flush();
            long now = System.currentTimeMillis();
            log.info("共耗时:{}",((now - old) / 1000.0) );
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(fileOS!=null){
                try {
                    fileOS.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 隐藏workbook中不需要的sheet页。
     * @param wb
     * @param page 显示页的sheet数组
     */
    public static void printSheetPage(Workbook wb,int[] page){
        for (int i= 1; i < wb.getWorksheets().getCount(); i++)  {
            wb.getWorksheets().get(i).setVisible(false);
        }
        if(null==page||page.length==0){
            wb.getWorksheets().get(0).setVisible(true);
        }else{
            for (int i = 0; i < page.length; i++) {
                wb.getWorksheets().get(i).setVisible(true);
            }
        }
    }

    /**
     * 设置打印的sheet 自动拉伸比例
     * @param wb
     * @param page 自动拉伸的页的sheet数组
     */
    public static void autoDraw(Workbook wb,int[] page){
        if(null!=page&&page.length>0){
            for (int i = 0; i < page.length; i++) {
                wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
                wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
            }
        }
    }

    public static void main(String[] args) {
        String inputExcelPath = "源文件地址";
        String outputPdfPath = "C:/gkzcwebfile/xxx.pdf";
        excel2pdf(inputExcelPath,outputPdfPath);
    }
}
package com.zngk.biz.modular.employeesSpace.utils;

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * word转换pdf
 */
@Log4j2
public class WordConvertPdfUtil {

    public static boolean getLicense() {
        boolean result = false;
        try {
            // license.xml应放在
            InputStream is = WordConvertPdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF
     * @param inPath 源文件路径
     * @param outPath 新pdf文件路径
     */
    public static void doc2pdf(String inPath, String outPath) {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            return;
        }
        log.info("开始转换doc==start");
        FileOutputStream os = null;
        try {
            long old = System.currentTimeMillis();
            // 新建一个空白pdf文档
            File file = new File(outPath);
            os = new FileOutputStream(file);
            // Address是将要被转化的word文档
            Document doc = new Document(inPath);
            // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            doc.save(os, SaveFormat.PDF);
            // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            // 转化用时
            log.info("共耗时:{}",((now - old) / 1000.0) );
        } catch (Exception e) {
            log.info("转换pdf报错==[{}]",e);
        }
        finally {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        String inPath = "源文件地址";
        String outPath ="C:Users/Asus/Desktop/aa.pdf";
        doc2pdf(inPath,outPath);
    }

}

六、下方是自定义水印的加入方式,代码有些长,同学可自行吧其中的对象换成自己项目中的

//本地暂存文件的目录    
private static String uploadDir = "C:/gkzcwebfile";
    private static char fileSeparator = '/';

//上传文件,贴这段代码的目的是因为,文件转pdf 较慢,文件越大转换越慢,我的处理方式是,在上传文件的时候用ThreadUtil.execute去转换,不耽误现有的接口使用
    @Override
    public String uploadReturnUrlOa(MultipartFile file, String folderName, String fileId) {
        return this.storageFileOa(file, false, folderName, fileId);
    }


//上传文件的具体实现
    private String storageFileOa(MultipartFile file, boolean returnFileId, String folderName, String fileId1) {
        BigDecimal a = NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024))//本次上传文件的大小
                .setScale(0, BigDecimal.ROUND_HALF_UP);
        if(isTure(a).equals("1")){
            return "1";
        }

        // 生成id
        String fileId = IdWorker.getIdStr();
        // 存储桶名称
        String bucketName = DevFileMinIoUtil.getDefaultBucketName();;
        // 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址
        String storageUrl = DevFileMinIoUtil.storageFileWithReturnUrl(bucketName, genFileKey(fileId, file), file);
        String suffix = ObjectUtil.isNotEmpty(file.getOriginalFilename())?StrUtil.subAfter(file.getOriginalFilename(),
                StrUtil.DOT, true):null;
        // 将文件信息保存到数据库
        DevFile devFile = new DevFile();
        // 如果是图片,则压缩生成缩略图
        if(ObjectUtil.isNotEmpty(suffix)) {
            if(isPic(suffix)) {
                try {
                    devFile.setThumbnail(ImgUtil.toBase64DataUri(ImgUtil.scale(ImgUtil.toImage(file.getBytes()),
                            100, 100, null), suffix));
                } catch (Exception ignored) {
                }
            }
        }

        // 设置文件id
        devFile.setId(fileId);
        // 设置存储引擎类型
        devFile.setEngine("MINIO");
        devFile.setBucket(bucketName);
        String originalFilename = file.getOriginalFilename();

        if(originalFilename.contains("/")){
            devFile.setName(originalFilename.split("/")[1]);
        }else{
            devFile.setName(originalFilename);
        }

        devFile.setSuffix(suffix);
        devFile.setSizeKb(Convert.toStr(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024))
                .setScale(0, BigDecimal.ROUND_HALF_UP)));
        devFile.setSizeInfo(FileUtil.readableFileSize(file.getSize()));
        devFile.setObjName(ObjectUtil.isNotEmpty(devFile.getSuffix())?fileId + StrUtil.DOT + devFile.getSuffix():null);
        // 存储路径
        devFile.setStoragePath(storageUrl);
        // 定义下载地址
        String downloadUrl;
        // MINIO可以直接使用存储地址(公网)作为下载地址
        downloadUrl= storageUrl;
        devFile.setDownloadPath(devFile.getStoragePath());
        devFileOaMapper.insert(devFile);

        //注意,需要设置序号,在树形菜单展示会用
        OaEmployeeSpaceFiles oaEmployeeSpaceFiles = new OaEmployeeSpaceFiles();
        oaEmployeeSpaceFiles.setFileCategory("文件");
        oaEmployeeSpaceFiles.setCategory("文件");
        oaEmployeeSpaceFiles.setOwner(StpLoginUserUtil.getLoginUser().getAccount());
        oaEmployeeSpaceFiles.setOwnerN(StpLoginUserUtil.getLoginUser().getName());
        oaEmployeeSpaceFiles.setFileId(fileId);
        oaEmployeeSpaceFiles.setParentId(fileId1);
        oaEmployeeSpaceFiles.setName(devFile.getName());
        //注意 要存kb 和 mb
        oaEmployeeSpaceFiles.setSizeInfo(FileUtil.readableFileSize(file.getSize()));
        oaEmployeeSpaceFiles.setSizeKb(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024))
                .setScale(0, BigDecimal.ROUND_HALF_UP));
        oaEmployeeSpaceFiles.setId(IdWorker.getIdStr());
        oaEmployeeSpaceFiles.setFileAddress(devFile.getStoragePath());
        oaEmployeeSpaceFiles.setCreateUserN(StpLoginUserUtil.getLoginUser().getName());
        this.save(oaEmployeeSpaceFiles);

        //使用多线转换成pdf文件,为了不耽误现有的接口使用
        demo(oaEmployeeSpaceFiles);

        // 如果是返回id则返回文件id
        if(returnFileId) {
            return fileId;
        } else {
            // 否则返回下载地址
            return downloadUrl;
        }
    }

 private void demo(OaEmployeeSpaceFiles oaEmployeeSpaceFiles){
        ThreadUtil.execute(() -> {
            String tempPdfFilePath = uploadDir + fileSeparator + UUID.randomUUID().toString() + ".pdf";
            File file1 = new File(tempPdfFilePath);
            //转成pdf
            if (oaEmployeeSpaceFiles.getFileAddress().contains(".doc") || oaEmployeeSpaceFiles.getFileAddress().contains(".docx")) {
                WordConvertPdfUtil.doc2pdf(oaEmployeeSpaceFiles.getFileAddress(), tempPdfFilePath);
            } else if (oaEmployeeSpaceFiles.getFileAddress().contains(".xls") || oaEmployeeSpaceFiles.getFileAddress().contains(".xlxs")) {
                ExcelConvertPdfUtil.excel2pdf(oaEmployeeSpaceFiles.getFileAddress(), tempPdfFilePath);
            } else if (oaEmployeeSpaceFiles.getFileAddress().contains(".pdf")) {

            } else if (oaEmployeeSpaceFiles.getFileAddress().contains(".ppt") || oaEmployeeSpaceFiles.getFileAddress().contains(".pptx")) {
                PptConvertPdfUtil.ppt2Pdf(oaEmployeeSpaceFiles.getFileAddress(), tempPdfFilePath);
            } else if (oaEmployeeSpaceFiles.getFileAddress().contains(".txt")) {
                TxtConvertPdfUtil.txt2Pdf(oaEmployeeSpaceFiles.getFileAddress(), tempPdfFilePath);
            }

            oaEmployeeSpaceFiles.setFileAddressPdf(tempPdfFilePath);
            this.updateById(oaEmployeeSpaceFiles);
        });
    }


//预览的方法,前端使用的是vue3+pdfjs
@Override
    public OaEmployeeSpaceFiles preview(OaEmployeeSpaceFilesPageParam oaEmployeeSpaceFilesPageParam) throws IOException {
        //加水印
        if (StringUtil.isEmpty(oaEmployeeSpaceFilesPageParam.getFileId())) {
            return new OaEmployeeSpaceFiles();
        }

        QueryWrapper<OaEmployeeSpaceFiles> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(OaEmployeeSpaceFiles::getFileId, oaEmployeeSpaceFilesPageParam.getFileId());
        List<OaEmployeeSpaceFiles> list = this.list(queryWrapper);
        OaEmployeeSpaceFiles oaEmployeeSpaceFiles = list.get(0);

        OaEmployeeSpaceFiles file = list.get(0);
        

        OaEmployeeSpaceWatermarkPageParam oaEmployeeSpaceWatermarkPageParam = new OaEmployeeSpaceWatermarkPageParam();
        Page<OaEmployeeSpaceWatermark> page = oaEmployeeSpaceWatermarkService.page(oaEmployeeSpaceWatermarkPageParam);
        LocalDate localDate = LocalDate.now();
        // 水印文本
        String watermarkText = "超管/superAdmin/2024-04-08";
        if(page.getRecords().size() > 0){
            OaEmployeeSpaceWatermark oa = page.getRecords().get(0);
            if(oa.getWatermarkContent().indexOf("姓名") != -1){
                watermarkText += StpLoginUserUtil.getLoginUser().getName();
            }

            if(oa.getWatermarkContent().indexOf("工号") != -1){
                watermarkText += StpLoginUserUtil.getLoginUser().getAccount();
            }

            if(oa.getWatermarkContent().indexOf("部门") != -1){
                watermarkText += "/" + StpLoginUserUtil.getLoginUser().getOrgName();
            }

            if(oa.getWatermarkContent().indexOf("时间") != -1){
                watermarkText += "/" + localDate;
            }
        }else{
            watermarkText = StpLoginUserUtil.getLoginUser().getName() + StpLoginUserUtil.getLoginUser().getAccount() + "/" + StpLoginUserUtil.getLoginUser().getOrgName() + "/" + localDate;
        }

        String pdfUrl = oaEmployeeSpaceFilesPageParam.getFileAddress();
        //图片也需要上传致服务器返回新的地址,加上水印
        if(oaEmployeeSpaceFilesPageParam.getFileType().equals("png") || oaEmployeeSpaceFilesPageParam.getFileType().equals("jpg")){
            String waterMarkImage = addWaterMarkImg(watermarkText, oaEmployeeSpaceFiles.getFileAddress(), oaEmployeeSpaceFilesPageParam.getFileType());
            byte[] bytes = IoUtil.readBytes(FileUtil.getInputStream(waterMarkImage));
            // 存储桶名称
            String bucketName = DevFileMinIoUtil.getDefaultBucketName();
            // 生成id
            String fileId = IdWorker.getIdStr();
            // 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址
            String storageUrl = DevFileMinIoUtil.storageFileWithReturnUrl(bucketName, genFileKeyByte(fileId, oaEmployeeSpaceFilesPageParam.getFileName()), bytes);
            System.err.println(storageUrl);
            oaEmployeeSpaceFiles.setFileAddress(storageUrl);
        }else {
            File fileDir = new File(uploadDir);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            String tempPdfFilePath = uploadDir + fileSeparator + UUID.randomUUID().toString()+".pdf";
            File file1 = new File(tempPdfFilePath);
            if(file.getFileAddressPdf() != null){
                tempPdfFilePath = file.getFileAddressPdf();
            }else{
                if(oaEmployeeSpaceFilesPageParam.getFileType().equals("doc") || oaEmployeeSpaceFilesPageParam.getFileType().equals("docx")){
                    WordConvertPdfUtil.doc2pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("xls") || oaEmployeeSpaceFilesPageParam.getFileType().equals("xlxs")){
                    ExcelConvertPdfUtil.excel2pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("pdf")){
                    // 下载PDF文件
                    try {
                        downloadPdf1(pdfUrl, file1);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("ppt")  || oaEmployeeSpaceFilesPageParam.getFileType().equals("pptx")){
                    PptConvertPdfUtil.ppt2Pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("txt")){
                    TxtConvertPdfUtil.txt2Pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }

                file.setFileAddressPdf(tempPdfFilePath);
            }

            String newtempPdfFilePath = uploadDir + fileSeparator + "NEW"+UUID.randomUUID().toString()+".pdf";
            // 添加水印
            try {
                addWaterMark(tempPdfFilePath, newtempPdfFilePath, watermarkText);
            } catch (Exception e) {
                e.printStackTrace();
            }

            File tempFile = new File(newtempPdfFilePath);
//我这边项目使用的是minio 上传文件
            byte[] bytes = IoUtil.readBytes(FileUtil.getInputStream(newtempPdfFilePath));
            // 存储桶名称
            String bucketName = DevFileMinIoUtil.getDefaultBucketName();
            // 生成id
            String fileId = IdWorker.getIdStr();
            // 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址
            String storageUrl = DevFileMinIoUtil.storageFileWithReturnUrl(bucketName, genFileKeyByte(fileId, oaEmployeeSpaceFilesPageParam.getFileName()), bytes);
            System.err.println(storageUrl);
//前端预览的是这个地址:storageUrl,使用的前端技术是pdfjs
            oaEmployeeSpaceFiles.setFileAddress(storageUrl);
        }
       
        return oaEmployeeSpaceFiles;
    }



//pdf文件添加水印的方法
 public static void addWaterMark(String inputFile, String outputFile, String waterMarkName) {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(inputFile);
            stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(outputFile)));
            //水印字体,放到服务器上对应文件夹下(arial中文不生效)
            //BaseFont base = BaseFont.createFont("D:/workspace/springboot/src/main/resources/arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            Rectangle pageRect;
            PdfGState gs = new PdfGState();
            //填充不透明度  为1完全不透明
            gs.setFillOpacity(0.05f);
            //笔画不透明度, 为1完全不透明
            gs.setStrokeOpacity(0.05f);
            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;
            int interval = 0;
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                //在字体下方加水印
                under = stamper.getOverContent(i);
                under.beginText();
                under.saveState();
                under.setGState(gs);
                under.setFontAndSize(base, 15);
                for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 5) {
                    for (int x = 0; x < 3; x++) {
                        under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 50, height - textH, 15);
                    }
                }

                for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 5) {
                    for (int x = 0; x < 3; x++) {
                        under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 300, height - textH, 15);
                    }
                }

                for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 5) {
                    for (int x = 0; x < 3; x++) {
                        under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 550, height - textH, 15);
                    }
                }

                for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 5) {
                    for (int x = 0; x < 3; x++) {
                        under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 850, height - textH, 15);
                    }
                }

                under.endText();
            }
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stamper != null) {
                    stamper.close();
                }
            } catch (IOException | com.itextpdf.text.DocumentException e) {
                e.printStackTrace();
            }
            if (reader != null) {
                reader.close();
            }
        }
    }


//图片添加水印的方法
 private static String addWaterMarkImg(String waterMarkContent, String fileAddress, String fileType) throws IOException {
        // 读取原图片信息 得到文件(本地图片)
        // File srcImgFile = new File(fileAddress);
        // InputStream inputStream = new FileInputStream(srcImgFile);

        //读取网络上的图片
        URL url = new URL(fileAddress);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        InputStream inputStream = connection.getInputStream();

        // 封装为BufferedInputStream,用于流文件类型读取后的重置
        BufferedInputStream bufferedInputStream  = new BufferedInputStream(inputStream);
        // 标记读取的文件类型长度
        bufferedInputStream.mark(HEADER_SIZE);
        // 重置流到开始位置
        bufferedInputStream.reset();
        BufferedImage targetImg = ImageIO.read(bufferedInputStream);
        int height = targetImg.getHeight();
        int width = targetImg.getWidth();
        BufferedImage waterMarkImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建画笔
        Graphics2D graphics2D = waterMarkImage.createGraphics();
        // 绘制原始图片
        graphics2D.drawImage(targetImg, 0, 0, width, height, null);

        // 设置水印颜色
        graphics2D.setColor(new Color(255, 255, 255, 50));

        double scale = 1.0;
        if(width < height){
            scale = (double) width / height;
        }
        int fontSize = (int) Math.ceil((double) (height / 45) * scale);
        // 设置字体 画笔字体样式为微软雅黑,加粗,文字大小按比例给
        graphics2D.setFont(new Font("微软雅黑", Font.BOLD, fontSize));

        // 水印旋转度
        graphics2D.rotate(Math.toRadians(-25), (double) width / 2, (double) height / 2);

        int x = -width * 3;
        int y;
        // 计算水印文字的宽度
        FontMetrics fontMetrics = graphics2D.getFontMetrics();
        int watermarkWidth = fontMetrics.stringWidth(waterMarkContent);
        // 水印横向间隔
        int positionWidth = (int)(width * 0.15);
        // 水印竖向间隔
        int positionHeight  = (int)(height * 0.15);

        while (x < width * 3) {
            y = -height * 3;
            while (y < height * 3) {
                graphics2D.drawString(waterMarkContent, x, y);
                y += fontSize + positionWidth;
            }
            x += watermarkWidth + positionHeight;
        }

        graphics2D.dispose();
        String tarImgPath = uploadDir + fileSeparator + UUID.randomUUID().toString()+"." + fileType;
        FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
        ImageIO.write(waterMarkImage, fileType, outImgStream);
        outImgStream.flush();
        outImgStream.close();
        return tarImgPath;
    }


//这里是下载文件的具体实现
 @Override
    public void download(OaEmployeeSpaceFilesPageParam oaEmployeeSpaceFilesPageParam,HttpServletResponse response) throws IOException {
        if (StringUtil.isEmpty(oaEmployeeSpaceFilesPageParam.getFileId())) {
            return;
        }


        OaEmployeeSpaceWatermarkPageParam oaEmployeeSpaceWatermarkPageParam = new OaEmployeeSpaceWatermarkPageParam();
        Page<OaEmployeeSpaceWatermark> page = oaEmployeeSpaceWatermarkService.page(oaEmployeeSpaceWatermarkPageParam);
        LocalDate localDate = LocalDate.now();
        // 水印文本
        String watermarkText = "超管/superAdmin/2024-04-08";
//        if(page.getRecords().size() > 0){
//            OaEmployeeSpaceWatermark oa = page.getRecords().get(0);
//            if(oa.getWatermarkContent().indexOf("姓名") != -1){
//                watermarkText += StpLoginUserUtil.getLoginUser().getName();
//            }
//
//            if(oa.getWatermarkContent().indexOf("工号") != -1){
//                watermarkText += StpLoginUserUtil.getLoginUser().getAccount();
//            }
//
//            if(oa.getWatermarkContent().indexOf("部门") != -1){
//                watermarkText += "/" + StpLoginUserUtil.getLoginUser().getOrgName();
//            }
//
//            if(oa.getWatermarkContent().indexOf("时间") != -1){
//                watermarkText += "/" + localDate;
//            }
//        }else{
//            watermarkText = StpLoginUserUtil.getLoginUser().getName() + StpLoginUserUtil.getLoginUser().getAccount() + "/" + StpLoginUserUtil.getLoginUser().getOrgName() + "/" + localDate;
//        }

        //源文件地址
        String pdfUrl = oaEmployeeSpaceFilesPageParam.getFileAddress();

        if(oaEmployeeSpaceFilesPageParam.getFileType().equals("png") || oaEmployeeSpaceFilesPageParam.getFileType().equals("jpg")){
            String waterMarkImage = addWaterMarkImg(watermarkText, oaEmployeeSpaceFilesPageParam.getFileAddress(), oaEmployeeSpaceFilesPageParam.getFileType());
//这个接口返回给前端的是给文件流,前端有的对应的下载文件代码,在本次代码的末尾,可进行参考
            CommonDownloadUtil.download(oaEmployeeSpaceFilesPageParam.getFileName(), IoUtil.readBytes(FileUtil.getInputStream(waterMarkImage)), response);
        }else {
            File fileDir = new File(uploadDir);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            String tempPdfFilePath = uploadDir + fileSeparator + UUID.randomUUID().toString()+".pdf";
            File file1 = new File(tempPdfFilePath);

            if(file.getFileAddressPdf() != null){
                tempPdfFilePath = file.getFileAddressPdf();
            }else{
                if(oaEmployeeSpaceFilesPageParam.getFileType().equals("doc") || oaEmployeeSpaceFilesPageParam.getFileType().equals("docx")){
                    WordConvertPdfUtil.doc2pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("xls") || oaEmployeeSpaceFilesPageParam.getFileType().equals("xlxs")){
                    ExcelConvertPdfUtil.excel2pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("pdf")){
                    // 下载PDF文件
                    try {
                        downloadPdf1(pdfUrl, file1);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("ppt")  || oaEmployeeSpaceFilesPageParam.getFileType().equals("pptx")){
                    PptConvertPdfUtil.ppt2Pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }else if(oaEmployeeSpaceFilesPageParam.getFileType().equals("txt")){
                    TxtConvertPdfUtil.txt2Pdf(oaEmployeeSpaceFilesPageParam.getFileAddress(), tempPdfFilePath);
                }

//这里读取的是上传的时候转码之后的pdf文件存放地址
                file.setFileAddressPdf(tempPdfFilePath);
            }

            this.updateById(file);

            String newtempPdfFilePath = uploadDir + fileSeparator + "NEW"+UUID.randomUUID().toString()+".pdf";
            // 添加水印
            try {
                addWaterMark(tempPdfFilePath, newtempPdfFilePath, watermarkText);
            } catch (Exception e) {
                e.printStackTrace();
            }

            File tempFile = new File(newtempPdfFilePath);
            CommonDownloadUtil.download(oaEmployeeSpaceFilesPageParam.getFileName(), IoUtil.readBytes(FileUtil.getInputStream(tempFile)), response);
        }
    }

//下载pdf文件
 public static void downloadPdf1(String pdfUrl, File file) throws IOException {
        URL url = new URL(pdfUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        InputStream inputStream = connection.getInputStream();

        FileOutputStream outputStream = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        outputStream.close();
        inputStream.close();
    }

//匹配文件格式
 private static boolean isPic(String fileSuffix) {
        fileSuffix = fileSuffix.toLowerCase();
        return ImgUtil.IMAGE_TYPE_GIF.equals(fileSuffix)
                || ImgUtil.IMAGE_TYPE_JPG.equals(fileSuffix)
                || ImgUtil.IMAGE_TYPE_JPEG.equals(fileSuffix)
                || ImgUtil.IMAGE_TYPE_BMP.equals(fileSuffix)
                || ImgUtil.IMAGE_TYPE_PNG.equals(fileSuffix)
                || ImgUtil.IMAGE_TYPE_PSD.equals(fileSuffix);
    }


 /**
     * 生成文件的key,格式如 2021/10/11/1377109572375810050.docx
     *
     * @author xuyuxiang
     * @date 2022/4/22 15:58
     **/
    public String genFileKey(String fileId, MultipartFile file) {

        // 获取文件原始名称
        String originalFileName = file.getOriginalFilename();

        // 获取文件后缀
        String fileSuffix = FileUtil.getSuffix(originalFileName);

        // 生成文件的对象名称,格式如:1377109572375810050.docx
        String fileObjectName = fileId + StrUtil.DOT + fileSuffix;

        // 获取日期文件夹,格式如,2021/10/11/
        String dateFolderPath = DateUtil.thisYear() + StrUtil.SLASH +
                (DateUtil.thisMonth() + 1) + StrUtil.SLASH +
                DateUtil.thisDayOfMonth() + StrUtil.SLASH;

        // 返回
        return dateFolderPath + fileObjectName;
    }


public String genFileKeyByte(String fileId, String fileName) {

        // 获取文件原始名称
        String originalFileName = fileName;

        // 获取文件后缀
        String fileSuffix = FileUtil.getSuffix(originalFileName);

        // 生成文件的对象名称,格式如:1377109572375810050.docx
        String fileObjectName = fileId + StrUtil.DOT + fileSuffix;

        // 获取日期文件夹,格式如,2021/10/11/
        String dateFolderPath = DateUtil.thisYear() + StrUtil.SLASH +
                (DateUtil.thisMonth() + 1) + StrUtil.SLASH +
                DateUtil.thisDayOfMonth() + StrUtil.SLASH;

        // 返回
        return dateFolderPath + fileObjectName;
    }


//以下是前端代码
const urlToBold = (res, fileType) => {
	// 将链接地址字符内容转变成blob地址
	const aLink = document.createElement('a')
	let href = window.URL.createObjectURL(res.data)
	let name = currentFile.value.name
	if(fileType == 'png' || fileType == 'jpg'){
		name=name.substr(0,name.lastIndexOf('.')) + '.' + fileType
	}else{
		name=name.substr(0,name.lastIndexOf('.'))  + '.pdf'
	}

	aLink.download = name
	aLink.href = href
	document.body.appendChild(aLink)
	aLink.click()
	document.body.removeChild(aLink) // 下载完成移除元素
	window.URL.revokeObjectURL(href) // 释放掉blob对象
}

描述:以上内容是记录自己工作中遇到的文件转pdf,加上水印的需求,也希望能帮助到有需要的同学

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值