Java实现http链接文件下载之后加文字水印再上传至OSS并返回一个http下载链接

需求:

        ①通过一个http链接将原文件(doc/docx/pdf)下载下来

        ②将下载下来的文件加入指定文字水印

        ③将加完水印的文件再上传至OSS,并返回一个可以下载的链接,将获得的链接入库

①:下载原文件:

String oldFileOssUrl="http/https://....";
URL url = new URL(oldFileOssUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
    String decode = URLDecoder.decode(oldFileOssUrl, "UTF-8");
    //根据"?"截取url问号之前的链接内容
    String url2 = decode.split("\\?")[0];
    //根据“/”截取获取最后一个元素即为文件名称
    String[] split = url2.split("/");
    String fileName = split[split.length-1];
    String fileUrl = "/home/"+fileName;
    //下载文件
    InputStream inputStream = connection.getInputStream();
    File outputFile = new File(fileUrl); // 保存文件的路径及名称
    OutputStream outputStream = new FileOutputStream(outputFile);
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
    outputStream.close();
    inputStream.close();
}

②给文件加水印:

1、给word文件加水印:

先用Maven引入依赖:

<dependency>
   <groupId>e-iceblue</groupId>
   <artifactId>spire.doc.free</artifactId>
   <version>5.2.0</version>
</dependency>

代码实现:

/**添加水印**/
//创建一个Document实例
Document document = new Document();
//上边获取的文件名
String fileName = "abc.docx"
//文件保存到本地的位置
String fileUrl = "/home/abc.docx";
//加载示例 Word 文档
document.loadFromFile(fileUrl);
//获取第一节
Section section = document.getSections().get(0);
//创建一个 TextWatermark 实例
TextWatermark txtWatermark = new TextWatermark();
//设置文本水印格式
txtWatermark.setText(watermarkText);
txtWatermark.setFontSize(120);
txtWatermark.setColor(Color.red);
txtWatermark.setLayout(WatermarkLayout.Diagonal);
//将文本水印添加到示例文档
section.getDocument().setWatermark(txtWatermark);
outputFile.delete();
String savePath = "/home/generater/"+fileName;
//保存文件到本地
document.saveToFile(savePath, FileFormat.Docx);

2、给pdf文件加水印:

引入Maven依赖:

<!-- 对PDF文件的操作 -->
<dependency>
   <groupId>com.itextpdf</groupId>
   <artifactId>itextpdf</artifactId>
   <version>5.5.13.1</version>
</dependency>
<!-- PDF文件 字体 防止中文乱码 -->
<dependency>
   <groupId>com.itextpdf</groupId>
   <artifactId>itext-asian</artifactId>
   <version>5.2.0</version>
</dependency>

代码实现:

//已经下载下来的文件位置
String fileUrl="/home/abc.pdf";
//上边已经获取的文件名称
String fileName="abc.pdf";
FileInputStream fileInputStream = new FileInputStream(fileUrl);
byte[] pdfFileBytes = IOUtils.toByteArray(fileInputStream);
String savePath = "/home/generater/"+fileName;
OutputStream outputFilePath = Files.newOutputStream(Paths.get(savePath));
try {
    // 原PDF文件
    PdfReader reader = new PdfReader(pdfFileBytes);
    // 输出的PDF文件内容
    PdfStamper stamper = new PdfStamper(reader, outputFilePath);
    // 字体 来源于 itext-asian jar包
    BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", true);
    PdfGState gs = new PdfGState();
    // 设置透明度
    gs.setFillOpacity(0.2f);
    gs.setStrokeOpacity(0.3f);
    int totalPage = reader.getNumberOfPages() + 1;
    for (int i = 1; i < totalPage; i++) {
        // 内容上层
        PdfContentByte content = stamper.getOverContent(i);
        content.beginText();
        // 字体添加透明度
        content.setGState(gs);
        // 添加字体大小等
        content.setFontAndSize(baseFont, 120);
        // 添加范围
        content.showTextAligned(Element.ALIGN_BOTTOM, Optional.ofNullable(waterMarkText).orElse(""), 100, 100, 45);
        content.endText();
    }
    // 关闭
    stamper.close();
    reader.close();
} catch (Exception e) {
    e.printStackTrace();
    return null;
}

③上传文件到OSS

将文件转换成MultipartFile对象: getMultipartFile()方法:

public static MultipartFile getMultipartFile(File file,String fileType) {
    String contentType="";
    if (fileType.toLowerCase().contains("pdf")) {
        contentType=MediaType.APPLICATION_PDF_VALUE;
    } else if (fileType.toLowerCase().equals("docx")) {
        contentType ="application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    } else if (fileType.toLowerCase().equals("doc")) {
        contentType ="application/msword";
    }
    FileItem item = new DiskFileItemFactory().createItem("file"
            , contentType
            , true
            , file.getName());
    try (InputStream input = new FileInputStream(file);
         OutputStream os = item.getOutputStream()) {
        // 流转移
        IOUtils.copy(input, os);
    } catch (Exception e) {
        throw new IllegalArgumentException("Invalid file: " + e, e);
    }
    return new CommonsMultipartFile(item);
}

上传方法不一定都适用,要根据自己上传接口的需求参考:

//从本地获取文件
File file = new File(savePath);
String[] fileTypes = fileName.split("\\.");
String fileType = fileTypes[fileTypes.length-1];
MultipartFile cMultiFile = Watermark.getMultipartFile(file,fileType);
CommonUploadAO ao = new CommonUploadAO();
ao.setBusinessType("pdf_type");
//调用封装好的上传接口
BaseResponse response = fileUploadService.upload(cMultiFile, ao);
FileVO vo = ConvertUtils.sourceToTarget(response.getData(), FileVO.class);
file.delete();
if (vo != null) {
    return vo.getPublicUrl();
} else {
    return null;
}

以下是我的完整代码(docx和pdf均已测试,doc未测):

import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import com.digital.cnzz.common.lib.api.BaseResponse;
import com.digital.cnzz.file.upload.ao.CommonUploadAO;
import com.digital.cnzz.file.upload.ao.FileVO;
import com.digital.cnzz.file.upload.service.FileUploadService;
import com.digital.cnzz.smart.community.dmanage.common.utils.ConvertUtils;
import com.digital.cnzz.smart.community.dmanage.core.utils.SpringContextUtils;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.TextWatermark;
import com.spire.doc.documents.WatermarkLayout;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.awt.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Optional;

@Slf4j
public class Watermark {

    //请求接口入口oldFileOssUrl:原文件http链接,watermarkText:水印内容,fileType文件类型(word/pdf)
    public static String getPublicUrlByHttpUrl(String oldFileOssUrl,String watermarkText,String fileType) throws IOException  {
        String publicUrl;
        if (fileType.contains("word")) {
            publicUrl = getWordWatermarkFilePath(oldFileOssUrl,watermarkText);
        } else {
            publicUrl = getPdfWatermarkFilePath(oldFileOssUrl,watermarkText);
        }
        return publicUrl;
    }

    public static MultipartFile getMultipartFile(File file,String fileType) {
        String contentType="";
        if (fileType.toLowerCase().contains("pdf")) {
            contentType=MediaType.APPLICATION_PDF_VALUE;
        } else if (fileType.toLowerCase().equals("docx")) {
            contentType ="application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        } else if (fileType.toLowerCase().equals("doc")) {
            contentType ="application/msword";
        }
        FileItem item = new DiskFileItemFactory().createItem("file"
                , contentType
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }
        return new CommonsMultipartFile(item);
    }

    public static String getWordWatermarkFilePath(String oldFileOssUrl,String watermarkText) throws IOException {
        FileUploadService fileUploadService = SpringContextUtils.getBean(FileUploadService.class);
        //根据Word文件的HTTP链接地址
        URL url = new URL(oldFileOssUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            String decode = URLDecoder.decode(oldFileOssUrl, "UTF-8");
            //根据"?"截取url问号之前的链接内容
            String url2 = decode.split("\\?")[0];
            //根据“/”截取获取最后一个元素即为文件名称
            String[] split = url2.split("/");
            String fileName = split[split.length-1];
            String fileUrl = "/home/"+fileName;
            //下载文件
            InputStream inputStream = connection.getInputStream();
            File outputFile = new File(fileUrl); // 保存Word文件的路径及名称
            OutputStream outputStream = new FileOutputStream(outputFile);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.close();
            inputStream.close();
            /**添加水印**/
            //创建一个Document实例
            Document document = new Document();
            //加载示例 Word 文档
            document.loadFromFile(fileUrl);
            //获取第一节
            Section section = document.getSections().get(0);
            //创建一个 TextWatermark 实例
            TextWatermark txtWatermark = new TextWatermark();
            //设置文本水印格式
            txtWatermark.setText(watermarkText);
            txtWatermark.setFontSize(120);
            txtWatermark.setColor(Color.red);
            txtWatermark.setLayout(WatermarkLayout.Diagonal);
            //将文本水印添加到示例文档
            section.getDocument().setWatermark(txtWatermark);
            outputFile.delete();
            String savePath = "/home/generater/"+fileName;
            //保存文件到本地
            document.saveToFile(savePath, FileFormat.Docx);
            //从本地获取文件
            File file = new File(savePath);
            String[] fileTypes = fileName.split("\\.");
            String fileType = fileTypes[fileTypes.length-1];
            MultipartFile cMultiFile = Watermark.getMultipartFile(file,fileType);
            CommonUploadAO ao = new CommonUploadAO();
            ao.setBusinessType("word_type");
            BaseResponse response = fileUploadService.upload(cMultiFile, ao);
            FileVO vo = ConvertUtils.sourceToTarget(response.getData(), FileVO.class);
            file.delete();
            if (vo != null) {
                return vo.getPublicUrl();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    public static String getPdfWatermarkFilePath(String oldFileOssUrl, String waterMarkText) throws IOException {
        FileUploadService fileUploadService = SpringContextUtils.getBean(FileUploadService.class);
        //根据pdf文件的HTTP链接地址
        URL url = new URL(oldFileOssUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            String decode = URLDecoder.decode(oldFileOssUrl, "UTF-8");
            //根据"?"截取url问号之前的链接内容
            String url2 = decode.split("\\?")[0];
            //根据“/”截取获取最后一个元素即为文件名称
            String[] split = url2.split("/");
            String fileName = split[split.length - 1];
            String fileUrl = "/home/" + fileName;
            //下载文件
            InputStream inputStream = connection.getInputStream();
            File outputFile = new File(fileUrl); // 保存Word文件的路径及名称
            OutputStream outputStream = new FileOutputStream(outputFile);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.close();
            inputStream.close();
            FileInputStream fileInputStream = new FileInputStream(fileUrl);
            byte[] pdfFileBytes = IOUtils.toByteArray(fileInputStream);
            String savePath = "/home/generater/"+fileName;
            OutputStream outputFilePath = Files.newOutputStream(Paths.get(savePath));
            try {
                // 原PDF文件
                PdfReader reader = new PdfReader(pdfFileBytes);
                // 输出的PDF文件内容
                PdfStamper stamper = new PdfStamper(reader, outputFilePath);
                // 字体 来源于 itext-asian jar包
                BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", true);
                PdfGState gs = new PdfGState();
                // 设置透明度
                gs.setFillOpacity(0.2f);
                gs.setStrokeOpacity(0.3f);
                int totalPage = reader.getNumberOfPages() + 1;
                for (int i = 1; i < totalPage; i++) {
                    // 内容上层
                    PdfContentByte content = stamper.getOverContent(i);
                    content.beginText();
                    // 字体添加透明度
                    content.setGState(gs);
                    // 添加字体大小等
                    content.setFontAndSize(baseFont, 120);
                    // 添加范围
                    content.showTextAligned(Element.ALIGN_BOTTOM, Optional.ofNullable(waterMarkText).orElse(""), 100, 100, 45);
                    content.endText();
                }
                // 关闭
                stamper.close();
                reader.close();
                //从本地获取文件
                File file = new File(savePath);
                String[] fileTypes = fileName.split("\\.");
                String fileType = fileTypes[fileTypes.length-1];
                MultipartFile cMultiFile = Watermark.getMultipartFile(file,fileType);
                CommonUploadAO ao = new CommonUploadAO();
                ao.setBusinessType("pdf_type");
                BaseResponse response = fileUploadService.upload(cMultiFile, ao);
                FileVO vo = ConvertUtils.sourceToTarget(response.getData(), FileVO.class);
                file.delete();
                if (vo != null) {
                    return vo.getPublicUrl();
                } else {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
    }
}

以上仅供参考,代码并没有优化,用的时候可以优化一下再用,希望能帮到着急的你。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值