需求:
①通过一个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;
}
}
}
以上仅供参考,代码并没有优化,用的时候可以优化一下再用,希望能帮到着急的你。