基于java实现zip文件下载,并添加水印
package com.research.business.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.research.common.core.domain.AjaxResult;
import com.research.process.mapper.CityAndCountyMapper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author zjl
* @description TODO
* @time: 2023/8/27 17:18
*/
@RestController
@RequestMapping("/downloadFile")
public class FileDownloadController {
private static final Logger log = LoggerFactory.getLogger(FileDownloadController.class);
@javax.annotation.Resource
private CityAndCountyMapper cityAndCountyMapper;
// 设置上传文件保存的目录
@Value("${file.UPLOAD_DIR}")
private String UPLOAD_DIR;
@PostMapping("/download")
public AjaxResult displayFile(@RequestBody JSONObject jsonObject, HttpServletResponse response) {
try {
//获取请求参数
String cityId = jsonObject.getString("cityId");
String userOa = jsonObject.getString("userOa");
// 构建文件路径
String directory = UPLOAD_DIR + "/pdf";
// String directory = UPLOAD_DIR + "\\pdf";
File dir = new File(directory);
File targetFile = null;
try {
if (dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().contains(cityId)) {
targetFile = file;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("查询经营概况文档失败");
return AjaxResult.error(500, "查询经营概况文档失败");
}
if (targetFile == null) {
log.error("未查询到该地区经营概况文档");
return AjaxResult.error(500, "未查询到该地区经营概况文档");
}
// 设置响应头信息
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=" + URLEncoder.encode(targetFile.getName(), "UTF-8"));
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
// 添加水印并获取带有水印的文件资源
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = currentDateTime.format(formatter);
String watermarkText = userOa + " " + formattedDateTime + " " + userOa + " " + formattedDateTime;
// 创建PDF文档对象
PDDocument document = PDDocument.load(targetFile);
// 获取页面数量
int pageCount = document.getNumberOfPages();
// 创建水印图形状态
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(0.1f); // 设置非描边元素的透明度
// 设置水印倾斜角度(以度为单位)
float rotationAngle = 30;
// 添加水印到每一页
for (int i = 0; i < pageCount; i++) {
PDPage page = document.getPage(i);
// 获取页面大小和宽度
PDRectangle mediaBox = page.getMediaBox();
float pageWidth = mediaBox.getWidth();
// 创建页面内容流
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
// 设置水印字体和大小
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 22);
// 设置水印透明度
contentStream.setGraphicsStateParameters(graphicsState);
// 开始绘制水印
contentStream.beginText();
// 设置水印位置和倾斜角度
contentStream.setTextMatrix(1, 0, 0, 1, 0, 0); // 原点在左下角
contentStream.setTextRotation(Math.toRadians(rotationAngle), 100, 100); // 设置水印倾斜角度和起始位置
// 添加水印文本
for (int j = 0; j < 3; j++) {
contentStream.showText(watermarkText);
contentStream.newLineAtOffset(0, 200); // 移动到下一行的起始位置
}
// 结束绘制水印
contentStream.endText();
// 关闭内容流
contentStream.close();
}
// 将带有水印的PDF文档写入响应流
document.save(response.getOutputStream());
document.close();
} catch (IOException e) {
log.error("解析经营概况文件失败");
return AjaxResult.error("解析经营概况文件失败");
}
return null;
}
/**
* @description 文件下载,单个文件直接下载,多个文件放入压缩包后下载
* @author zjl91
* @param[1] null
* @time 2023/10/8 17:12
*/
@PostMapping("/downloadPdf")
public ResponseEntity<Resource> downloadFile(@RequestBody JSONObject jsonObject) throws IOException {
// 构建文件路径
String directory = UPLOAD_DIR + "/pdf/";
// String directory = UPLOAD_DIR + "\\pdf\\";
//解析传入的json数据
JSONArray researchCountyList = jsonObject.getJSONArray("researchCountyList");
String userOa = jsonObject.getString("userOa");
//根据当前登录人账号和时间生成水印文本
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = currentDateTime.format(formatter);
String watermarkText = userOa + " " + formattedDateTime + " " + userOa + " " + formattedDateTime;
if (researchCountyList.size() == 1) {
//获取请求参数
String cityId = (String) researchCountyList.get(0);
File dir = new File(directory);
File targetFile = null;
if (dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().contains(cityId)) {
targetFile = file;
}
}
}
}
//如果查询到对应的pdf文档,则进行下载
if (!(targetFile == null)) {
// 添加水印并获取带有水印的文件资源
String filePath = directory + researchCountyList.get(0) + ".pdf";
Resource resource = addWatermarkAndDownload(filePath, watermarkText, cityId);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + directory + cityId + ".pdf");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} else {
log.error("未查询到编码为" + cityId + "地市的经营概况文档!");
}
} else {
File dir = new File(directory);
// 创建临时压缩文件
File zipFile = new File(UPLOAD_DIR + "/" + "files.zip");
// File zipFile = new File("D:/research/temp/pdfs.zip");
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
for (int i = 0; i < researchCountyList.size(); i++) {
File targetFile = null;
String cityId = researchCountyList.get(i).toString();
if (dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().contains(cityId)) {
targetFile = file;
}
}
}
}
//如果查询到对应的pdf文档,则把文档放入压缩包中
if (!(targetFile == null)) {
String filename = cityId + ".pdf";
Path file = Paths.get(directory + filename);
//根据地市编码获取地市的名称(重命名pdf文档的名称)
String cityName = cityAndCountyMapper.selectById(cityId);
String newFilename = cityName + ".pdf";
ZipEntry zipEntry = new ZipEntry(newFilename);
zos.putNextEntry(zipEntry);
// 添加水印并下载带有水印的PDF文件
Resource watermarkedPdf = addWatermarkAndDownload(file.toString(), watermarkText, cityId);
if (watermarkedPdf != null) {
Path watermarkedPdfPath = watermarkedPdf.getFile().toPath();
Files.copy(watermarkedPdfPath, zos);
}
zos.closeEntry();
} else {
log.error("未查询到编码为" + researchCountyList.get(i) + "地市的经营概况文档!");
}
}
//关闭流
zos.close();
fos.close();
// 创建压缩包资源
FileSystemResource resource = new FileSystemResource(zipFile);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=pdfs.zip");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}
return null;
}
/**
* @description 给文件添加水印
* @author zjl91
* @param[1] String filePath 需要添加水印的文件路径
* @param[2] String watermarkText 水印的内容(当前登录人账号+日期)
* @param[3] String fileName 添加水印的文件名称(无后缀的)
* @time 2023/10/9 9:32
*/
private Resource addWatermarkAndDownload(String filePath, String watermarkText, String fileName) {
try {
// 加载PDF文档
PDDocument document = PDDocument.load(new File(filePath));
// 获取页面数量
int pageCount = document.getNumberOfPages();
// 创建水印图形状态
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(0.1f); // 设置非描边元素的透明度
// 设置水印倾斜角度(以度为单位)
float rotationAngle = 30;
// 添加水印到每一页
for (int i = 0; i < pageCount; i++) {
PDPage page = document.getPage(i);
// 获取页面大小和宽度
PDRectangle mediaBox = page.getMediaBox();
float pageWidth = mediaBox.getWidth();
// 创建页面内容流
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
// 设置水印字体和大小
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 22);
// 设置水印透明度
contentStream.setGraphicsStateParameters(graphicsState);
// 开始绘制水印
contentStream.beginText();
// 设置水印位置和倾斜角度
contentStream.setTextMatrix(1, 0, 0, 1, 0, 0); // 原点在左下角
contentStream.setTextRotation(Math.toRadians(rotationAngle), 100, 100); // 设置水印倾斜角度和起始位置
// 添加水印文本,三行
for (int j = 0; j < 3; j++) {
contentStream.showText(watermarkText);
contentStream.newLineAtOffset(0, 200); // 移动到下一行的起始位置
}
// 结束绘制水印
contentStream.endText();
// 关闭内容流
contentStream.close();
}
// 构建文件路径
String directory = UPLOAD_DIR + "/watermarkedPdf/";
File targetDirectoryFile = new File(directory);
//当转存路径不存在时,生成转存路径(用于保存添加了水印的文件)
if (!targetDirectoryFile.exists()) {
targetDirectoryFile.mkdirs();
}
// 保存修改后的PDF文件
String watermarkedFilePath = directory + fileName + "_watermarked.pdf";
document.save(watermarkedFilePath);
// 关闭文档
document.close();
// 创建文件资源
return new FileSystemResource(watermarkedFilePath);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
朝聞道,夕可眠矣。

浙公网安备 33010602011771号