springboot生成PDF,并且添加水印


	/**
	 *  导出调查问卷
	 */
	@ApiLog("导出调查问卷")
	@PostMapping("/print/{id}")
	@ApiOperationSupport(order = 23)
	@ApiOperation(value = "导出报告", notes = "导出报告")
	public void print(@PathVariable Long id, HttpServletResponse response) {
		BackendGradeEntity record = backendGradeService.getById(id);

		//如果record为空,直接返回错误信息
		if(record == null){
			throw new RuntimeException("未找到该记录");
		}

		Map values = new HashMap<>();
		Field[] fields = BackendGradeEntity.class.getDeclaredFields();
		//通过反射拿到对象的属性名并且赋值给map
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				Object value = field.get(record);
				values.put(field.getName(), value);
			} catch (IllegalAccessException e) {
				// 处理访问异常
				e.printStackTrace();
			}
		}

		//通过用户id查询用户信息
		BackendUserinformationEntity user = backendUserinformationService.getById(record.getUserId());
		//获取用户性别
		Integer sex = null;
		if (user!= null){
			sex = user.getSex();
		}

		//添加用户性别
		values.put("sex", sex==1?"男":"女");

		String totalTime = values.get("totalTime").toString();
		double timeInSeconds = Double.parseDouble(totalTime) * 60; // 将分钟转换为秒
		int minutes = (int) timeInSeconds / 60;
		int seconds = (int) timeInSeconds % 60;
		String formattedTime = minutes + "分钟" + seconds + "秒";
		values.put("totalTime", formattedTime);

		//增加打印日期为当前日期
		values.put("printDate", DateUtil.format(LocalDate.now(), "yyyy年MM月dd日"));
		//修改map中的startTime 和 endTime 格式由2023-09-19T15:34:25  为 2023-09-19 15:34:25
		String startTime = values.get("startTime").toString().replace("T", " ");
		String endTime = values.get("endTime").toString().replace("T", " ");
		values.put("startTime", startTime);
		values.put("endTime", endTime);

		//将 正确率 错误率 未答题率 乘100再填回,因为数据存的是小数
		values.put("errorRate", Double.parseDouble(values.get("errorRate").toString())*100);
		values.put("accuracy", Double.parseDouble(values.get("accuracy").toString())*100);
		values.put("unansweredRate", Double.parseDouble(values.get("unansweredRate").toString())*100);



		String fileName = null;
		String tplName = null;
		if(true){
			fileName = "报告";
			tplName = "intuitionReport.ftl";
		}
		fileName = fileName + "-" + (values.get("userName")==null?UUID.randomUUID():values.get("userName"));
		String file = printer.print(values, tplName, fileName);

		//下载文件
		InputStream inStream = null;
		try {
			inStream = new FileInputStream(file);
			response.reset();
			response.setContentType("application/pdf");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(new File(file).getName(), "UTF-8"));
			response.setCharacterEncoding("UTF-8");
			IoUtil.copy(inStream, response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (inStream != null) {
				try { inStream.close(); } catch (IOException e) { e.printStackTrace(); }
			}
		}
	}


	/**
	 *  批量导出报告
	 */
	@ApiLog("批量导出报告")
	@PostMapping("/print/batch")
	@ApiOperationSupport(order = 23)
	@ApiOperation(value = "批量导出", notes = "批量导出报告")
	public void printBatch(@RequestParam String ids, HttpServletResponse response) {
		List records = backendGradeService.listByIds(Func.toLongList(ids));

		String uuid = UUID.randomUUID().toString();

		int size = records.size();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String zipName = LocalDateTime.now().format(formatter)+"-"+size+"records.zip";

		Path zipPath = Paths.get(pathProperties.getPdf(), zipName);
		File zipFile = zipPath.toFile();
		if(zipFile.exists()){
			zipFile.delete();//如果文件存在则先删除旧的文件
		}

		List files = null;
		try{
			if(!zipFile.getParentFile().exists()){
				Files.createDirectories(zipPath.getParent());
			}

			files = records.stream()
//				.filter(j -> j.getStatus() == 4)
				.map(record -> {

					Map values = new HashMap<>();
					Field[] fields = BackendGradeEntity.class.getDeclaredFields();
					//通过反射拿到对象的属性名并且赋值给map
					for (Field field : fields) {
						field.setAccessible(true);
						try {
							Object value = field.get(record);
							values.put(field.getName(), value);
						} catch (IllegalAccessException e) {
							// 处理访问异常
							e.printStackTrace();
						}
					}


					//通过用户id查询用户信息
					BackendUserinformationEntity user = backendUserinformationService.getById(record.getUserId());
					//获取用户性别
					Integer sex = null;
					if (user!= null){
						sex = user.getSex();
					}

					//添加用户性别
					values.put("sex", sex==1?"男":"女");

					//处理总时长
					String totalTime = values.get("totalTime").toString();
					double timeInSeconds = Double.parseDouble(totalTime) * 60; // 将分钟转换为秒
					int minutes = (int) timeInSeconds / 60;
					int seconds = (int) timeInSeconds % 60;
					String formattedTime = minutes + "分钟" + seconds + "秒";
					values.put("totalTime", formattedTime);

					//增加打印日期为当前日期
					values.put("printDate", DateUtil.format(LocalDate.now(), "yyyy年MM月dd日"));
					//修改map中的startTime 和 endTime 格式由2023-09-19T15:34:25  为 2023-09-19 15:34:25
					String startTime = values.get("startTime").toString().replace("T", " ");
					String endTime = values.get("endTime").toString().replace("T", " ");
					values.put("startTime", startTime);
					values.put("endTime", endTime);


					//将 正确率 错误率 未答题率 乘100再填回,因为数据存的是小数
					values.put("errorRate", Double.parseDouble(values.get("errorRate").toString())*100);
					values.put("accuracy", Double.parseDouble(values.get("accuracy").toString())*100);
					values.put("unansweredRate", Double.parseDouble(values.get("unansweredRate").toString())*100);


					String fileName = null;
					String tplName = null;
					if(true){
						fileName = "报告";
						tplName = "intuitionReport.ftl";
					}
					fileName = fileName + "-" + (values.get("userName")==null?UUID.randomUUID():values.get("userName")+UUID.randomUUID().toString());
					String f = printer.print(values, tplName, uuid+"/"+fileName);
					return new File(f);
				}).collect(Collectors.toList());


//			Path tempDir = Files.createTempDirectory("temp");
//			List copiedFiles = new ArrayList<>();
//			for (File file : files) {
//				Path source = Paths.get(file.getPath());
//				Path destination = tempDir.resolve(file.getName());
//				Files.copy(source, destination);
//				copiedFiles.add(destination.toFile());
//			}
//			// 在这里调用添加水印的方法
//			PDFWatermarkExample.addWatermarkExample(copiedFiles);
//
//			files = copiedFiles;
//			try {
//				// 删除临时文件夹及其所有文件
//				FileUtils.deleteDirectory(tempDir.toFile());
//			} catch (IOException e) {
//				// 处理删除错误
//				e.printStackTrace();
//			}

			ZipTool.zipFile(files, zipPath.toFile().getAbsolutePath());
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			if(files != null){
				for(File f : files){
					if(f.exists()) f.delete();
				}
			}
			Path dirPath = Paths.get(pathProperties.getPdf(), uuid);
			if(dirPath.toFile().exists()){
				dirPath.toFile().delete();
			}
		}

		//下载文件
		InputStream inStream = null;
		try {
			if(!zipFile.exists()){
				return ;
			}
			inStream = new FileInputStream(zipFile);
			response.reset();
			response.setContentType("application/zip");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
			response.setCharacterEncoding("UTF-8");
			IoUtil.copy(inStream, response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (inStream != null) {
				try { inStream.close(); } catch (IOException e) { e.printStackTrace(); }
			}
		}

		//这里删除临时文件夹内的压缩包,因为存着也没什么用浪费空间
		//通过zipPath获取绝对路径
		String absolutePath = zipPath.toFile().getAbsolutePath();
		//删除absolutepath文件夹,以及所有文件
		deleteDirectoryRecursively(new File(absolutePath));


	}

下面是加水印

package org.springblade.common.tool;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

public class PDFWatermarkExample {
	public static void addWatermark(String inputFile, String outputFile, String watermarkText) {
		try {
			PdfReader reader = new PdfReader(inputFile);
			PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
			int numberOfPages = reader.getNumberOfPages();

			for (int i = 1; i <= numberOfPages; i++) {
				PdfContentByte content = stamper.getUnderContent(i);
				PdfGState gs = new PdfGState();
				gs.setFillOpacity(0.5f); // 设置水印透明度
				content.setGState(gs);

				ColumnText.showTextAligned(
					content,
					Element.ALIGN_CENTER,
					new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),
					reader.getPageSizeWithRotation(i).getWidth() / 2,
					reader.getPageSizeWithRotation(i).getHeight() / 2,
					45
				);
			}

			stamper.close();
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void addWatermarkMulti(String inputFile, String outputFile, String watermarkText) {
		try {
			PdfReader reader = new PdfReader(inputFile);
			PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
			int numberOfPages = reader.getNumberOfPages();

			for (int i = 1; i <= numberOfPages; i++) {
				PdfContentByte content = stamper.getOverContent(i);
				PdfGState gs = new PdfGState();
				gs.setFillOpacity(0.05f); // 设置水印透明度
				content.setGState(gs);

				Rectangle pageSize = reader.getPageSizeWithRotation(i);
				float pageWidth = pageSize.getWidth();
				float pageHeight = pageSize.getHeight();

				// 设置水印间隔
				float xInterval = 200; // X轴间隔
				float yInterval = 50; // Y轴间隔

				// 计算水印个数
				int xCount = (int) Math.ceil(pageWidth / xInterval);
				int yCount = (int) Math.ceil(pageHeight / yInterval);

				// 平铺水印
				for (int x = 0; x < xCount; x++) {
					for (int y = 0; y < yCount; y++) {
						float xPosition = x * xInterval;
						float yPosition = y * yInterval;

						ColumnText.showTextAligned(
							content,
							Element.ALIGN_CENTER,
							new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),
							xPosition,
							yPosition,
							0
						);
					}
				}
			}

			stamper.close();
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void addWatermarkExample(List files) {
		// 在这里编写添加水印的代码逻辑,使用上面提到的添加水印的示例代码
		for (File file : files) {
			addWatermark(file.getPath(), file.getPath(), "Watermark Text");
		}
	}

	public static void main(String[] args) {
		String inputFile = "C:\\Users\\admin\\Downloads\\123.pdf";
		String outputFile = "C:\\Users\\admin\\Downloads\\789.pdf";
		String watermarkText = "zhijue.com";

		addWatermarkMulti(inputFile, outputFile, watermarkText);
	}
}

你可能感兴趣的:(spring,boot,pdf,java)