springboot生成PDF,并且添加水印

news/2025/2/2 13:51:32/
/***  导出调查问卷*/@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<String, Object> values = new HashMap<>();Field[] fields = BackendGradeEntity.class.getDeclaredFields();//通过反射拿到对象的属性名并且赋值给mapfor (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:25String 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<BackendGradeEntity> 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<File> files = null;try{if(!zipFile.getParentFile().exists()){Files.createDirectories(zipPath.getParent());}files = records.stream()
//				.filter(j -> j.getStatus() == 4).map(record -> {Map<String, Object> values = new HashMap<>();Field[] fields = BackendGradeEntity.class.getDeclaredFields();//通过反射拿到对象的属性名并且赋值给mapfor (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:25String 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<File> 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<File> 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);}
}


http://www.ppmy.cn/news/1226913.html

相关文章

【QT基础入门】QT中的控件类概述

QT控件类的概述: QT是一个跨平台的应用程序开发框架,它提供了一系列的控件类,用于创建和管理用户界面。控件类是继承自QObject的类,它们可以接收用户的输入,显示信息,或者提供布局和容器功能。控件类通常有以下几个特点: 控件类可以拥有自己的属性、方法和信号,用于控…

macOS 后台项目已添加 “Google Updater添加了可在后台运行的项目。你可以在“登陆项”设置中管理

文章目录 Intro解决查看三个文件夹分析 & 操作确认结果是否生效 Intro 我的macbook上经常弹出这样的通知狂&#xff1a; macOS 后台项目已添加 “Google Updater添加了可在后台运行的项目。你可以在“登陆项”设置中管理 不胜其扰&#xff0c;终于决定禁用它。以下为方法…

Halcon (3):窗体常用语法使用

文章目录 文章专栏视频资源前言halcon图像使用加载图片示例绘制常用图像批量批注绘制 文章专栏 Halcon开发 视频资源 机器视觉之C#联合Halcon 前言 在使用halcon的算子之前&#xff0c;我们要先学会如何在图片上面进行标注。因为我们不仅要导出处理的结果&#xff0c;还要导出…

Linux - 驱动开发 - RNG框架

说明 公司SOC上有一个新思的真随机数&#xff08;TRNG&#xff09;模块&#xff0c;Linux平台上需要提供接口给外部使用。早期方式是提供一个独立的TRNG驱动&#xff0c;实现比较简单的&#xff0c;但是使用方式不open&#xff0c;为了加入Linux生态环境&#xff0c;对接linux…

python——第十天

今日目标&#xff1a; 常见排序和查找 常见排序和查找: 冒泡排序 选择排序 插入排序 选择排序&#xff1a; 假设"第一个值"是最小值&#xff0c;就要每一轮找到真正的最小值&#xff0c;并且和假设的这个值交换 [1, 3, 2, 10, -8, 9, -30, 7] 1、 [-30, 3, 2, 10, -8…

如何从Android恢复出厂设置后的手机恢复数据

如果您已使用出厂设置删除了Android设备上的所有数据&#xff0c;或者有一段时间未使用&#xff0c;则需要恢复出厂设置以从Android设备中检索数据。 奇客数据恢复安卓版是一个有用的工具&#xff0c;可以在重置后检索Android数据。 将Android设备恢复出厂设置 如果您需要将A…

webAPP基础学习

###视觉基础 part-I ####1.面试中常见的像素问题 >什么是像素? *1.什么是px? px-虚拟像素,css像素的单位 px是一个相对单位,相对于设备像素而言 >相对性 a.相对于同一个设备,css像素的可变的 css像素物理像素>会受到缩放的影响 css像素缩放倍数*单个物理像…

搜索二叉树(二叉搜索树)的实现(递归与非递归)

一、搜索二叉树的概念 搜索二叉树又称二叉排序树&#xff0c;二叉搜索树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点…