• springboot生成PDF,并且添加水印


    1. /**
    2. * 导出调查问卷
    3. */
    4. @ApiLog("导出调查问卷")
    5. @PostMapping("/print/{id}")
    6. @ApiOperationSupport(order = 23)
    7. @ApiOperation(value = "导出报告", notes = "导出报告")
    8. public void print(@PathVariable Long id, HttpServletResponse response) {
    9. BackendGradeEntity record = backendGradeService.getById(id);
    10. //如果record为空,直接返回错误信息
    11. if(record == null){
    12. throw new RuntimeException("未找到该记录");
    13. }
    14. Map values = new HashMap<>();
    15. Field[] fields = BackendGradeEntity.class.getDeclaredFields();
    16. //通过反射拿到对象的属性名并且赋值给map
    17. for (Field field : fields) {
    18. field.setAccessible(true);
    19. try {
    20. Object value = field.get(record);
    21. values.put(field.getName(), value);
    22. } catch (IllegalAccessException e) {
    23. // 处理访问异常
    24. e.printStackTrace();
    25. }
    26. }
    27. //通过用户id查询用户信息
    28. BackendUserinformationEntity user = backendUserinformationService.getById(record.getUserId());
    29. //获取用户性别
    30. Integer sex = null;
    31. if (user!= null){
    32. sex = user.getSex();
    33. }
    34. //添加用户性别
    35. values.put("sex", sex==1?"男":"女");
    36. String totalTime = values.get("totalTime").toString();
    37. double timeInSeconds = Double.parseDouble(totalTime) * 60; // 将分钟转换为秒
    38. int minutes = (int) timeInSeconds / 60;
    39. int seconds = (int) timeInSeconds % 60;
    40. String formattedTime = minutes + "分钟" + seconds + "秒";
    41. values.put("totalTime", formattedTime);
    42. //增加打印日期为当前日期
    43. values.put("printDate", DateUtil.format(LocalDate.now(), "yyyy年MM月dd日"));
    44. //修改map中的startTime 和 endTime 格式由2023-09-19T15:34:25 为 2023-09-19 15:34:25
    45. String startTime = values.get("startTime").toString().replace("T", " ");
    46. String endTime = values.get("endTime").toString().replace("T", " ");
    47. values.put("startTime", startTime);
    48. values.put("endTime", endTime);
    49. //将 正确率 错误率 未答题率 乘100再填回,因为数据存的是小数
    50. values.put("errorRate", Double.parseDouble(values.get("errorRate").toString())*100);
    51. values.put("accuracy", Double.parseDouble(values.get("accuracy").toString())*100);
    52. values.put("unansweredRate", Double.parseDouble(values.get("unansweredRate").toString())*100);
    53. String fileName = null;
    54. String tplName = null;
    55. if(true){
    56. fileName = "报告";
    57. tplName = "intuitionReport.ftl";
    58. }
    59. fileName = fileName + "-" + (values.get("userName")==null?UUID.randomUUID():values.get("userName"));
    60. String file = printer.print(values, tplName, fileName);
    61. //下载文件
    62. InputStream inStream = null;
    63. try {
    64. inStream = new FileInputStream(file);
    65. response.reset();
    66. response.setContentType("application/pdf");
    67. response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(new File(file).getName(), "UTF-8"));
    68. response.setCharacterEncoding("UTF-8");
    69. IoUtil.copy(inStream, response.getOutputStream());
    70. } catch (Exception e) {
    71. e.printStackTrace();
    72. } finally {
    73. if (inStream != null) {
    74. try { inStream.close(); } catch (IOException e) { e.printStackTrace(); }
    75. }
    76. }
    77. }
    78. /**
    79. * 批量导出报告
    80. */
    81. @ApiLog("批量导出报告")
    82. @PostMapping("/print/batch")
    83. @ApiOperationSupport(order = 23)
    84. @ApiOperation(value = "批量导出", notes = "批量导出报告")
    85. public void printBatch(@RequestParam String ids, HttpServletResponse response) {
    86. List records = backendGradeService.listByIds(Func.toLongList(ids));
    87. String uuid = UUID.randomUUID().toString();
    88. int size = records.size();
    89. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    90. String zipName = LocalDateTime.now().format(formatter)+"-"+size+"records.zip";
    91. Path zipPath = Paths.get(pathProperties.getPdf(), zipName);
    92. File zipFile = zipPath.toFile();
    93. if(zipFile.exists()){
    94. zipFile.delete();//如果文件存在则先删除旧的文件
    95. }
    96. List files = null;
    97. try{
    98. if(!zipFile.getParentFile().exists()){
    99. Files.createDirectories(zipPath.getParent());
    100. }
    101. files = records.stream()
    102. // .filter(j -> j.getStatus() == 4)
    103. .map(record -> {
    104. Map values = new HashMap<>();
    105. Field[] fields = BackendGradeEntity.class.getDeclaredFields();
    106. //通过反射拿到对象的属性名并且赋值给map
    107. for (Field field : fields) {
    108. field.setAccessible(true);
    109. try {
    110. Object value = field.get(record);
    111. values.put(field.getName(), value);
    112. } catch (IllegalAccessException e) {
    113. // 处理访问异常
    114. e.printStackTrace();
    115. }
    116. }
    117. //通过用户id查询用户信息
    118. BackendUserinformationEntity user = backendUserinformationService.getById(record.getUserId());
    119. //获取用户性别
    120. Integer sex = null;
    121. if (user!= null){
    122. sex = user.getSex();
    123. }
    124. //添加用户性别
    125. values.put("sex", sex==1?"男":"女");
    126. //处理总时长
    127. String totalTime = values.get("totalTime").toString();
    128. double timeInSeconds = Double.parseDouble(totalTime) * 60; // 将分钟转换为秒
    129. int minutes = (int) timeInSeconds / 60;
    130. int seconds = (int) timeInSeconds % 60;
    131. String formattedTime = minutes + "分钟" + seconds + "秒";
    132. values.put("totalTime", formattedTime);
    133. //增加打印日期为当前日期
    134. values.put("printDate", DateUtil.format(LocalDate.now(), "yyyy年MM月dd日"));
    135. //修改map中的startTime 和 endTime 格式由2023-09-19T15:34:25 为 2023-09-19 15:34:25
    136. String startTime = values.get("startTime").toString().replace("T", " ");
    137. String endTime = values.get("endTime").toString().replace("T", " ");
    138. values.put("startTime", startTime);
    139. values.put("endTime", endTime);
    140. //将 正确率 错误率 未答题率 乘100再填回,因为数据存的是小数
    141. values.put("errorRate", Double.parseDouble(values.get("errorRate").toString())*100);
    142. values.put("accuracy", Double.parseDouble(values.get("accuracy").toString())*100);
    143. values.put("unansweredRate", Double.parseDouble(values.get("unansweredRate").toString())*100);
    144. String fileName = null;
    145. String tplName = null;
    146. if(true){
    147. fileName = "报告";
    148. tplName = "intuitionReport.ftl";
    149. }
    150. fileName = fileName + "-" + (values.get("userName")==null?UUID.randomUUID():values.get("userName")+UUID.randomUUID().toString());
    151. String f = printer.print(values, tplName, uuid+"/"+fileName);
    152. return new File(f);
    153. }).collect(Collectors.toList());
    154. // Path tempDir = Files.createTempDirectory("temp");
    155. // List copiedFiles = new ArrayList<>();
    156. // for (File file : files) {
    157. // Path source = Paths.get(file.getPath());
    158. // Path destination = tempDir.resolve(file.getName());
    159. // Files.copy(source, destination);
    160. // copiedFiles.add(destination.toFile());
    161. // }
    162. // // 在这里调用添加水印的方法
    163. // PDFWatermarkExample.addWatermarkExample(copiedFiles);
    164. //
    165. // files = copiedFiles;
    166. // try {
    167. // // 删除临时文件夹及其所有文件
    168. // FileUtils.deleteDirectory(tempDir.toFile());
    169. // } catch (IOException e) {
    170. // // 处理删除错误
    171. // e.printStackTrace();
    172. // }
    173. ZipTool.zipFile(files, zipPath.toFile().getAbsolutePath());
    174. }catch(Exception e){
    175. e.printStackTrace();
    176. }finally {
    177. if(files != null){
    178. for(File f : files){
    179. if(f.exists()) f.delete();
    180. }
    181. }
    182. Path dirPath = Paths.get(pathProperties.getPdf(), uuid);
    183. if(dirPath.toFile().exists()){
    184. dirPath.toFile().delete();
    185. }
    186. }
    187. //下载文件
    188. InputStream inStream = null;
    189. try {
    190. if(!zipFile.exists()){
    191. return ;
    192. }
    193. inStream = new FileInputStream(zipFile);
    194. response.reset();
    195. response.setContentType("application/zip");
    196. response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
    197. response.setCharacterEncoding("UTF-8");
    198. IoUtil.copy(inStream, response.getOutputStream());
    199. } catch (Exception e) {
    200. e.printStackTrace();
    201. } finally {
    202. if (inStream != null) {
    203. try { inStream.close(); } catch (IOException e) { e.printStackTrace(); }
    204. }
    205. }
    206. //这里删除临时文件夹内的压缩包,因为存着也没什么用浪费空间
    207. //通过zipPath获取绝对路径
    208. String absolutePath = zipPath.toFile().getAbsolutePath();
    209. //删除absolutepath文件夹,以及所有文件
    210. deleteDirectoryRecursively(new File(absolutePath));
    211. }

    下面是加水印

    1. package org.springblade.common.tool;
    2. import com.itextpdf.text.*;
    3. import com.itextpdf.text.pdf.*;
    4. import java.io.File;
    5. import java.io.FileOutputStream;
    6. import java.util.List;
    7. public class PDFWatermarkExample {
    8. public static void addWatermark(String inputFile, String outputFile, String watermarkText) {
    9. try {
    10. PdfReader reader = new PdfReader(inputFile);
    11. PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
    12. int numberOfPages = reader.getNumberOfPages();
    13. for (int i = 1; i <= numberOfPages; i++) {
    14. PdfContentByte content = stamper.getUnderContent(i);
    15. PdfGState gs = new PdfGState();
    16. gs.setFillOpacity(0.5f); // 设置水印透明度
    17. content.setGState(gs);
    18. ColumnText.showTextAligned(
    19. content,
    20. Element.ALIGN_CENTER,
    21. new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),
    22. reader.getPageSizeWithRotation(i).getWidth() / 2,
    23. reader.getPageSizeWithRotation(i).getHeight() / 2,
    24. 45
    25. );
    26. }
    27. stamper.close();
    28. reader.close();
    29. } catch (Exception e) {
    30. e.printStackTrace();
    31. }
    32. }
    33. public static void addWatermarkMulti(String inputFile, String outputFile, String watermarkText) {
    34. try {
    35. PdfReader reader = new PdfReader(inputFile);
    36. PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
    37. int numberOfPages = reader.getNumberOfPages();
    38. for (int i = 1; i <= numberOfPages; i++) {
    39. PdfContentByte content = stamper.getOverContent(i);
    40. PdfGState gs = new PdfGState();
    41. gs.setFillOpacity(0.05f); // 设置水印透明度
    42. content.setGState(gs);
    43. Rectangle pageSize = reader.getPageSizeWithRotation(i);
    44. float pageWidth = pageSize.getWidth();
    45. float pageHeight = pageSize.getHeight();
    46. // 设置水印间隔
    47. float xInterval = 200; // X轴间隔
    48. float yInterval = 50; // Y轴间隔
    49. // 计算水印个数
    50. int xCount = (int) Math.ceil(pageWidth / xInterval);
    51. int yCount = (int) Math.ceil(pageHeight / yInterval);
    52. // 平铺水印
    53. for (int x = 0; x < xCount; x++) {
    54. for (int y = 0; y < yCount; y++) {
    55. float xPosition = x * xInterval;
    56. float yPosition = y * yInterval;
    57. ColumnText.showTextAligned(
    58. content,
    59. Element.ALIGN_CENTER,
    60. new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),
    61. xPosition,
    62. yPosition,
    63. 0
    64. );
    65. }
    66. }
    67. }
    68. stamper.close();
    69. reader.close();
    70. } catch (Exception e) {
    71. e.printStackTrace();
    72. }
    73. }
    74. public static void addWatermarkExample(List files) {
    75. // 在这里编写添加水印的代码逻辑,使用上面提到的添加水印的示例代码
    76. for (File file : files) {
    77. addWatermark(file.getPath(), file.getPath(), "Watermark Text");
    78. }
    79. }
    80. public static void main(String[] args) {
    81. String inputFile = "C:\\Users\\admin\\Downloads\\123.pdf";
    82. String outputFile = "C:\\Users\\admin\\Downloads\\789.pdf";
    83. String watermarkText = "zhijue.com";
    84. addWatermarkMulti(inputFile, outputFile, watermarkText);
    85. }
    86. }

  • 相关阅读:
    目标检测——YOLOv2算法解读
    迪拜推出国家元宇宙战略
    WRFV3.8.1编译报错,无法显示exe文件
    艾美捷FcyRl (CD64),FCGR1A,生物活性活动分析结果
    Android 面经总结分享(相当走心)
    双目视觉实战---三维重建基础与极几何
    【吴恩达笔记】卷积神经网络
    不会代码的时候,如何使用Jmeter完成接口测试?
    不要在问了!工作六年总结的Java面试题与经验
    VBA技术资料MF50:VBA_在Excel中突出显示前3个值
  • 原文地址:https://blog.csdn.net/weixin_42759398/article/details/134442956