diff --git a/pom.xml b/pom.xml index cb370af..1e6d509 100644 --- a/pom.xml +++ b/pom.xml @@ -34,12 +34,42 @@ 0.9.1 6.7.2 1.9.6 + 6.7.2 + 6.7.2 + 6.7.2 + 6.7.2 + 6.7.2 - + + com.itextpdf + itextpdf + 5.5.13 + + + com.itextpdf.tool + xmlworker + 5.5.13 + + + com.itextpdf + itext-asian + 5.2.0 + + + org.xhtmlrenderer + flying-saucer-pdf + 9.0.3 + + + + org.freemarker + freemarker + 2.3.28 + org.springframework.boot diff --git a/ruoyi-admin/src/main/resources/font/simsun.ttc b/ruoyi-admin/src/main/resources/font/simsun.ttc new file mode 100644 index 0000000..23d5c4a Binary files /dev/null and b/ruoyi-admin/src/main/resources/font/simsun.ttc differ diff --git a/ruoyi-admin/src/main/resources/photo/watermark.jpg b/ruoyi-admin/src/main/resources/photo/watermark.jpg new file mode 100644 index 0000000..5788849 Binary files /dev/null and b/ruoyi-admin/src/main/resources/photo/watermark.jpg differ diff --git a/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl b/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl new file mode 100644 index 0000000..f6d8df0 --- /dev/null +++ b/ruoyi-admin/src/main/resources/template/COURSE_FEEDBACK.ftl @@ -0,0 +1,83 @@ + + + + + + + + + + +
+

课程反馈表

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
专业 Program${program!}学生姓名 Name${studentName!}
上课时间${startClassTime!}授课老师 Tutor${tutor!}
下课时间${endClassTime!}
作业完成情况
+ Feedback
${feedback!}
课堂表现
+ Performance
${performance!}
课堂内容
+ Content
${content!}
课后作业
+ Work
${work!}
+ 学生签字: +
+ +
+ + + \ No newline at end of file diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index bcee698..a718db2 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -136,6 +136,28 @@ hutool-all 5.8.11
+ + + com.itextpdf + itextpdf + + + com.itextpdf.tool + xmlworker + + + com.itextpdf + itext-asian + + + org.xhtmlrenderer + flying-saucer-pdf + + + + org.freemarker + freemarker +
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 new file mode 100644 index 0000000..7656085 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PdfUtils.java @@ -0,0 +1,68 @@ +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 freemarker.template.Configuration; +import freemarker.template.Template; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ResourceUtils; +import org.xhtmlrenderer.pdf.ITextRenderer; + +import java.io.File; +import java.io.OutputStream; +import java.io.StringWriter; +import java.util.Locale; + +/** + * @author yuxiangyong + * @create 2023-05-21 10:38 + */ +@Slf4j +public class PdfUtils { + + private final static String TEMPLATE_BASE_PATH = "/template/";//存放文件模板的地址 + private final static String IMG_BASE_PATH = "/photo/";//存放图片文件的地址(logo图片、机构公章等) + private final static String DEFAULT_FONT = "font/simsun.ttc";//默认字体资源文件([宋体][simsun.ttc]) + private final static String ENCODING = "UTF-8";//指定编码 + + /** + * 生成pdf + * @param templateCode 模板 + * @param data 传入到freemarker模板里的数据 + * @param out 生成的pdf文件流 + */ + public static void createPDF(String templateCode, Object data, OutputStream out, String imgName) { + try { + // 创建一个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)); + ITextRenderer renderer = new ITextRenderer(); + // 设置 css中 的字体样式(暂时仅支持宋体和黑体) + String fontPath = path + DEFAULT_FONT; + renderer.getFontResolver().addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + // 设置模板的编码格式 + cfg.setEncoding(Locale.CHINA, ENCODING); + // 获取模板文件 template.ftl + Template template = cfg.getTemplate(templateCode, ENCODING); + StringWriter writer = new StringWriter(); + // 将数据输出到html中 + template.process(data, writer); + writer.flush(); + String html = writer.toString(); + // 把html代码传入渲染器中 + renderer.setDocumentFromString(html); + renderer.layout(); + renderer.createPDF(out, false); + renderer.finishPDF(); + out.flush(); + out.close(); + } catch (Exception e) { + log.error("PDF导出异常", e); + } + } + +} 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 9bd0ab7..06cb38c 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 @@ -1,14 +1,17 @@ package com.ruoyi.flyingbook.controller; import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.utils.PdfUtils; import com.ruoyi.flyingbook.domain.edi.EdiResponseVo; import com.ruoyi.flyingbook.domain.edi.SyncToTableRequest; +import com.ruoyi.flyingbook.domain.template.CourseFeedbackTemplateDto; import com.ruoyi.flyingbook.edi.EdiOperateService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; @Slf4j @@ -21,9 +24,20 @@ public class EdiController extends BaseController { /** * 同步数据到飞书表格 */ - @PostMapping("/sync2Table") - public EdiResponseVo sync2Table(@RequestBody SyncToTableRequest request) { - return ediOperateService.sync2Table(request); +// @PostMapping("/sync2Table") +// public EdiResponseVo sync2Table(@RequestBody SyncToTableRequest request) { +// return ediOperateService.sync2Table(request); +// } + + @RequestMapping("sync2Table") + @ResponseBody + public void exportPdfDemo(HttpServletResponse response, @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(),""); } } 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 new file mode 100644 index 0000000..b9058f4 --- /dev/null +++ b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/domain/template/CourseFeedbackTemplateDto.java @@ -0,0 +1,30 @@ +package com.ruoyi.flyingbook.domain.template; + +import lombok.Data; + +/** + * @author yuxiangyong + * @create 2023-05-21 10:56 + */ +@Data +public class CourseFeedbackTemplateDto { + + private String templateUrl; + + private String watermark; + + private String program; + private String studentName; + private String startClassTime; + private String endClassTime; + private String tutor; + private String feedback; + private String performance; + private String content; + private String work; + + + + + +} diff --git a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/edi/impl/EdiOperateServiceImpl.java b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/edi/impl/EdiOperateServiceImpl.java index d144279..3a7f106 100644 --- a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/edi/impl/EdiOperateServiceImpl.java +++ b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/edi/impl/EdiOperateServiceImpl.java @@ -28,6 +28,7 @@ import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; import javax.annotation.Resource; import java.time.LocalDateTime; @@ -73,7 +74,7 @@ public class EdiOperateServiceImpl implements EdiOperateService { vo.setSuccessFlag(Boolean.TRUE); }catch (Exception e){ - log.error("同步数据到飞书异常"); + log.error("同步数据到飞书异常",e); vo.setSuccessFlag(Boolean.FALSE); vo.setErrorMessage(e.getMessage()); EventLog log = new EventLog(request.getEventId(), EventOperateType.SYNC_DATA_TO_TABLE.getCode(), JSONObject.toJSONString(request), null, e.getMessage()); @@ -114,13 +115,19 @@ public class EdiOperateServiceImpl implements EdiOperateService { */ private void buildRequestBodyList(SyncToTableRequest request,List errorList){ //多维表格行记录 + StopWatch stopWatch = new StopWatch("同步记录耗时"); + stopWatch.start("total"); for (SyncTableRowDetailRequest rowDetail : request.getRowDetailList()) { this.createRecord(rowDetail,request,errorList); } + stopWatch.stop(); + System.out.println(stopWatch.getTotalTimeSeconds()); } private void createRecord(SyncTableRowDetailRequest rowDetail,SyncToTableRequest request,List errorList){ Map body = new HashMap<>(); + StopWatch stopWatch = new StopWatch("同步记录耗时明细"); + stopWatch.start("detail"); try { List configurationList = request.getConfigurationList(); LarkCompanyRelation larkCompanyRelation = request.getLarkCompanyRelation(); @@ -139,6 +146,9 @@ public class EdiOperateServiceImpl implements EdiOperateService { log.error("同步行记录失败 request:{} larkRequest:{}",JSONObject.toJSONString(rowDetail),JSONObject.toJSONString(body)); EventLog log = new EventLog(request.getEventId(), EventOperateType.SYNC_DATA_TO_TABLE.getCode(), JSONObject.toJSONString(rowDetail), null, e.getMessage()); errorList.add(log); + }finally { + stopWatch.stop(); + System.out.println(stopWatch.getTotalTimeSeconds()); } }