From 10824d0a70396b83a93a7f723fdbdedda99e1e7c Mon Sep 17 00:00:00 2001 From: YXY <932687738@qq.com> Date: Sun, 21 May 2023 15:56:55 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90pdf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/template/COURSE_FEEDBACK.ftl | 22 ++-- .../java/com/ruoyi/common/utils/PdfUtils.java | 122 ++++++++++++++++-- .../flyingbook/controller/EdiController.java | 23 +++- .../template/CourseFeedbackTemplateDto.java | 2 + 4 files changed, 141 insertions(+), 28 deletions(-) diff --git a/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl b/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl index f6d8df0..c82f588 100644 --- a/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl +++ b/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl @@ -22,12 +22,16 @@ box-shadow: none; line-height: 30px; margin: 0px 10%; - height: auto !important; - padding: 0px 75px 100px 75px !important; + } + table{ + height:700px } .sign { margin-left: 70%; } + .bigRow{ + height: 180px; + } @@ -35,7 +39,7 @@

课程反馈表

- +
@@ -53,22 +57,22 @@ - + - + - + - + - + - + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PdfUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PdfUtils.java index 7656085..5145804 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PdfUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PdfUtils.java @@ -2,16 +2,19 @@ package com.ruoyi.common.utils; import cn.hutool.core.io.resource.ClassPathResource; import cn.hutool.core.io.resource.Resource; -import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Image; +import com.itextpdf.text.pdf.*; import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; import org.springframework.util.ResourceUtils; import org.xhtmlrenderer.pdf.ITextRenderer; -import java.io.File; -import java.io.OutputStream; -import java.io.StringWriter; +import java.io.*; import java.util.Locale; /** @@ -19,6 +22,7 @@ import java.util.Locale; * @create 2023-05-21 10:38 */ @Slf4j +@Component public class PdfUtils { private final static String TEMPLATE_BASE_PATH = "/template/";//存放文件模板的地址 @@ -26,23 +30,46 @@ public class PdfUtils { private final static String DEFAULT_FONT = "font/simsun.ttc";//默认字体资源文件([宋体][simsun.ttc]) private final static String ENCODING = "UTF-8";//指定编码 + + public void createFile(String templateCode, Object data){ + try { + String templatePath = ResourceUtils.getURL("classpath:").getPath(); + createPDF(templateCode,data,templatePath); + waterMark(getPath("test.pdf"),templatePath+"photo/watermark.jpg"); + }catch (Exception e){ + log.error("PDF导出异常", e); + } + + } + private String getPath(String fileName){ + return System.getProperty("user.dir") + "/" + fileName; + } + + private FileOutputStream getOutputStream(String fileName) throws IOException { + String path = getPath(fileName); + File file = new File(path); + if (!file.exists()){ + file.createNewFile(); + } + return new FileOutputStream(file); + } /** * 生成pdf * @param templateCode 模板 * @param data 传入到freemarker模板里的数据 - * @param out 生成的pdf文件流 */ - public static void createPDF(String templateCode, Object data, OutputStream out, String imgName) { + public void createPDF(String templateCode, Object data, String templatePath) { + FileOutputStream fileOutputStream = null; try { + fileOutputStream = getOutputStream("test.pdf"); // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例 Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); - String path = ResourceUtils.getURL("classpath:").getPath(); // 指定FreeMarker模板文件的位置 - cfg.setDirectoryForTemplateLoading(new File(path + TEMPLATE_BASE_PATH)); + cfg.setDirectoryForTemplateLoading(new File(templatePath + TEMPLATE_BASE_PATH)); ITextRenderer renderer = new ITextRenderer(); // 设置 css中 的字体样式(暂时仅支持宋体和黑体) - String fontPath = path + DEFAULT_FONT; + String fontPath = templatePath + DEFAULT_FONT; renderer.getFontResolver().addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 设置模板的编码格式 cfg.setEncoding(Locale.CHINA, ENCODING); @@ -56,12 +83,83 @@ public class PdfUtils { // 把html代码传入渲染器中 renderer.setDocumentFromString(html); renderer.layout(); - renderer.createPDF(out, false); + renderer.createPDF(fileOutputStream, false); renderer.finishPDF(); - out.flush(); - out.close(); + fileOutputStream.flush(); } catch (Exception e) { log.error("PDF导出异常", e); + }finally { + if (fileOutputStream != null) { + try { + fileOutputStream.flush(); + fileOutputStream.close(); + } catch (final IOException e) { + log.error("failed to close outputStream!", e); + } + } + } + } + + public boolean waterMark(String inputFile, String picFilePath) throws IOException, DocumentException { + PdfReader reader = null; + PdfStamper stamper = null; + FileOutputStream fileOutputStream = null; + try { + int picRowNum = 7; + int picColNum = 4; + float transDegree = 0.5f; + reader = new PdfReader(inputFile); + fileOutputStream = getOutputStream("test1.pdf"); + stamper = new PdfStamper(reader,fileOutputStream); + // 设置水印支持中文 + BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);// 使用系统字体 + int total = reader.getNumberOfPages() + 1; + PdfContentByte watermark; + // 遍历pdf文件的每页以处理 + for (int i = 1; i < total; i++) { + // 获得PDF最顶层 + watermark = stamper.getUnderContent(i); //在内容上方加水印 + watermark.saveState(); + PdfGState gs = new PdfGState(); + // 设置透明度范围为0到1 + gs.setFillOpacity(transDegree); + watermark.setGState(gs); + watermark.beginText(); + watermark.setFontAndSize(base, 15); //字体大小 + watermark.setColorFill(BaseColor.BLACK); //字体颜色 + for (int col = 1; col < picColNum+1; col++) { + for (int row = 1; row < picRowNum+1; row++) { + if (picFilePath != null || !"".contentEquals(picFilePath)) { + // 设置图片水印 + Image image = Image.getInstance(picFilePath); + image.setAbsolutePosition(100f, 250f); + image.scaleAbsolute(500, 500); // 自定义大小 + watermark.setGState(gs); // 设置透明度 + watermark.addImage(image); // 添加水印图片 + } + } + } + // 添加水印文字 + watermark.endText(); + watermark.setLineWidth(1f); + watermark.stroke(); + } + stamper.close(); + reader.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + }finally { + if (stamper != null){ + stamper.close(); + } + if (reader != null){ + reader.close(); + } + if (fileOutputStream != null){ + fileOutputStream.close(); + } + return false; } } diff --git a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/controller/EdiController.java b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/controller/EdiController.java index 06cb38c..cea97c5 100644 --- a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/controller/EdiController.java +++ b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/controller/EdiController.java @@ -11,6 +11,7 @@ import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -20,6 +21,8 @@ public class EdiController extends BaseController { @Autowired private EdiOperateService ediOperateService; + @Resource + private PdfUtils pdfUtils; /** * 同步数据到飞书表格 @@ -30,14 +33,20 @@ public class EdiController extends BaseController { // } @RequestMapping("sync2Table") - @ResponseBody - public void exportPdfDemo(HttpServletResponse response, @RequestParam("param")String param) throws Exception{ + public void exportPdfDemo(@RequestParam("param")String param) throws Exception{ CourseFeedbackTemplateDto resultDTO = new CourseFeedbackTemplateDto(); - resultDTO.setWatermark("");//设置图片,没有图片设置空即可 - resultDTO.setTemplateUrl("COURSE_FEEDBACK");//参数 - resultDTO.setProgram("aaaa"); - resultDTO.setStudentName("aaaa"); - PdfUtils.createPDF("COURSE_FEEDBACK.ftl",resultDTO,response.getOutputStream(),""); + resultDTO.setProgram("program"); + resultDTO.setStudentName("student"); + resultDTO.setTutor("tutor"); + resultDTO.setStartClassTime("2023-05-21 15:51:45"); + resultDTO.setEndClassTime("2023-05-22 15:51:45"); + resultDTO.setFeedback("作业完成情况"); + resultDTO.setFeedbackScore("7 /10"); + resultDTO.setPerformance("课堂表现"); + resultDTO.setPerformanceScore("9/10"); + resultDTO.setContent("

1、课堂内容1

1、课堂内容2

"); + resultDTO.setWork("

1、课后作业1

1、课后作业2

1、课后作业3

"); + pdfUtils.createFile("COURSE_FEEDBACK.ftl",resultDTO); } } diff --git a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/domain/template/CourseFeedbackTemplateDto.java b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/domain/template/CourseFeedbackTemplateDto.java index b9058f4..6653fe6 100644 --- a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/domain/template/CourseFeedbackTemplateDto.java +++ b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/domain/template/CourseFeedbackTemplateDto.java @@ -19,7 +19,9 @@ public class CourseFeedbackTemplateDto { private String endClassTime; private String tutor; private String feedback; + private String feedbackScore; private String performance; + private String performanceScore; private String content; private String work;
专业 Program ${program!}${endClassTime!}
作业完成情况
Feedback
${feedback!}评分 ${feedbackScore}
${feedback!}
课堂表现
Performance
${performance!}评分 ${performanceScore}
${performance!}
课堂内容
Content
${content!}
课后作业
Work
${work!}