wangliang преди 11 месеца
родител
ревизия
b317ff5996

+ 214 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java

@@ -540,6 +540,220 @@ public class PdfUtil {
         return null;
         return null;
     }
     }
 
 
+    /**
+     * pdf添加水印
+     *
+     * @param inputFile     需要添加水印的文件
+     * @param waterMarkName 需要添加的水印文字
+     * @param opacity       水印字体透明度(0-1)
+     * @param fontsize      水印字体大小
+     * @param rotation      水印倾斜角度(0-360)
+     */
+    public static File addWaterMarkNew(File inputFile, String[] waterMarkName, float opacity, int fontsize, int rotation) {
+        if (!inputFile.exists()) {
+            throw ExceptionResultEnum.ERROR.exception("试卷文件不存在");
+        }
+
+        if (waterMarkName.length == 0) {
+            return inputFile;
+        }
+
+        PdfReader reader = null;
+        PdfStamper stamper = null;
+        File outputFile = null;
+        try {
+            outputFile = new File(inputFile.getPath());
+            if (!outputFile.exists()) {
+                outputFile.getParentFile().mkdirs();
+                outputFile.createNewFile();
+            }
+            reader = new PdfReader(new FileInputStream(inputFile));
+            stamper = new PdfStamper(reader, new FileOutputStream(inputFile));
+            BaseFont base = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED);
+            PdfGState gs = new PdfGState();
+            //这里是透明度设置
+            gs.setFillOpacity(opacity);
+            //这里是条纹不透明度
+            gs.setStrokeOpacity(0.2f);
+            int total = reader.getNumberOfPages() + 1;
+            int textH = 0;
+            int textW = 0;
+            for (String s : waterMarkName) {
+                JLabel label = new JLabel();
+                FontMetrics metrics;
+
+                label.setText(s);
+                metrics = label.getFontMetrics(label.getFont());
+                //字符串的高,   只和字体有关
+                textH = metrics.getHeight();
+                //字符串的宽
+                textW = metrics.stringWidth(label.getText());
+            }
+
+            Rectangle pageRect;
+            PdfContentByte under;
+            for (int i = 1; i < total; i++) {
+                // 只打奇数页水印
+                pageRect = reader.getPageSizeWithRotation(i);
+                under = stamper.getOverContent(i);  //在内容上方添加水印
+                under.saveState();
+                under.setGState(gs);
+                under.beginText();
+                under.setFontAndSize(base, fontsize); //这里是水印字体大小
+                for (int j = 0; j < waterMarkName.length; j++) {
+                    under.showTextAligned(Element.ALIGN_LEFT, waterMarkName[j], 20, pageRect.getHeight() - 20 - (j * textH), rotation);
+                }
+                //添加水印文字
+                under.endText();
+            }
+            return outputFile;
+        } catch (IOException | DocumentException e) {
+            System.out.println("添加水印失败!错误信息为: " + e);
+            e.printStackTrace();
+        } finally {
+            //关闭流
+            if (stamper != null) {
+                try {
+                    stamper.close();
+                } catch (DocumentException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (reader != null) {
+                reader.close();
+            }
+            if (outputFile.exists()) {
+//                outputFile.delete();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * pdf生成水印(全屏)
+     *
+     * @param inputFile     插入前的文件路径
+     * @param waterMarkName 水印文案
+     * @throws Exception
+     */
+    public static void addWaterMarkFullScreen(File inputFile, String[] waterMarkName) throws Exception {
+        PdfReader reader = new PdfReader(new FileInputStream(inputFile));
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(inputFile));
+        PdfGState gs = new PdfGState();
+
+        // 设置字体
+        BaseFont font = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED);
+
+        // 设置透明度
+        gs.setFillOpacity(0.2f);
+
+        int total = reader.getNumberOfPages() + 1;
+        PdfContentByte content;
+        for (int i = 1; i < total; i++) {
+            content = stamper.getOverContent(i);
+            content.beginText();
+            content.setGState(gs);
+            // 水印颜色
+            content.setColorFill(BaseColor.BLUE);
+            // 水印字体样式和大小
+            content.setFontAndSize(font, 20);
+
+            // 获取页面尺寸
+            Rectangle pageSize = reader.getPageSize(i);
+            float pageWidth = pageSize.getWidth();
+            float pageHeight = pageSize.getHeight();
+
+            // 计算水印位置,覆盖整个页面
+            float x = 0;
+            float y = 0;
+            float rotation = 30; // 水印旋转角度
+
+            // 循环插入水印
+            while (x < pageWidth && y < pageHeight) {
+                for (int j = 0; j < waterMarkName.length; j++) {
+                    content.showTextAligned(Element.ALIGN_CENTER, waterMarkName[j], x, y, rotation);
+                }
+                // 水平平移
+                x += 200;
+                // 垂直平移
+                if (x >= pageWidth) {
+                    x = 0;
+                    y += 200;
+                }
+            }
+            content.endText();
+        }
+        stamper.close();
+    }
+
+    public static void waterMark(File inputFile, String waterMarkName, String password) {
+        try {
+            PdfReader reader = new PdfReader(new FileInputStream(inputFile));
+            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
+                    inputFile));
+
+            byte[] ownerPassword = password.getBytes();
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_ASSEMBLY, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_COPY, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_DEGRADED_PRINTING, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_FILL_IN, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_MODIFY_ANNOTATIONS, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_MODIFY_CONTENTS, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_PRINTING, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_SCREENREADERS, false);
+            stamper.setEncryption(null, ownerPassword, PdfWriter.DO_NOT_ENCRYPT_METADATA, true);
+            stamper.setViewerPreferences(PdfWriter.HideToolbar | PdfWriter.HideMenubar);
+
+            BaseFont font = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED);
+
+            Rectangle pageRect = null;
+            PdfGState gs = new PdfGState();
+            gs.setFillOpacity(0.3f);
+            gs.setStrokeOpacity(0.4f);
+            int total = reader.getNumberOfPages() + 1;
+
+            JLabel label = new JLabel();
+            int interval = -5;
+            FontMetrics metrics;
+            int textH = 0;
+            int textW = 0;
+            label.setText(waterMarkName);
+            metrics = label.getFontMetrics(label.getFont());
+            textH = metrics.getHeight();//字符串的高,   只和字体有关
+            textW = metrics.stringWidth(label.getText());//字符串的宽
+
+            PdfContentByte under;
+            for (int i = 1; i < total; i++) {
+                pageRect = reader.getPageSizeWithRotation(i);
+                // 计算水印X,Y坐标
+                float x = pageRect.getWidth() / 2;
+                float y = pageRect.getHeight() / 2;
+                under = stamper.getOverContent(i);
+                under.saveState();
+                under.setGState(gs);
+                under.beginText();
+                under.setFontAndSize(font, 15);
+                // 水印文字成45度角倾斜
+                for (int height = interval + textH; height < pageRect.getHeight();
+                     height = height + textH * 8) {
+                    for (int width = interval + textW; width < pageRect.getWidth() + textW;
+                         width = width + textW) {
+                        under.showTextAligned(Element.ALIGN_LEFT
+                                , waterMarkName, width - textW,
+                                height - textH, 45);
+                    }
+                }
+                // 添加水印文字
+                under.endText();
+            }
+            stamper.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     /**
     /**
      * html转pdf文件
      * html转pdf文件
      *
      *

+ 7 - 0
distributed-print/pom.xml

@@ -44,6 +44,13 @@
             <groupId>com.qmth.teachcloud.common.api</groupId>
             <groupId>com.qmth.teachcloud.common.api</groupId>
             <artifactId>teachcloud-common-api</artifactId>
             <artifactId>teachcloud-common-api</artifactId>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>com.aspose.words</groupId>
+            <artifactId>aspose-words-jdk16</artifactId>
+            <version>15.8.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
+        </dependency>
         <dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
             <artifactId>spring-boot-starter-web</artifactId>

+ 17 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/obe/TRBasicInfoController.java

@@ -11,6 +11,8 @@ import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.boot.core.rateLimit.annotation.RateLimit;
 import com.qmth.boot.core.rateLimit.annotation.RateLimit;
 import com.qmth.distributed.print.business.service.PrintCommonService;
 import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.distributed.print.business.util.PdfUtil;
+import com.qmth.distributed.print.util.WordToPdfUtil;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.BasicCourse;
@@ -391,4 +393,19 @@ public class TRBasicInfoController {
         }
         }
         return ResultUtil.ok(reportChangeResult);
         return ResultUtil.ok(reportChangeResult);
     }
     }
+
+    @Resource
+    WordToPdfUtil wordToPdfUtil;
+
+    @ApiOperation(value = "wordtopdf测试")
+    @RequestMapping(value = "/wordTopdf", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "转换成功", response = Object.class)})
+    @Aac(auth = false)
+    public Result wordTopdfTest() throws Exception {
+        wordToPdfUtil.wordToPdf("/Users/king/Downloads/测试学校_1_2021~2022第一学期_上学期《电力电子与电力传动》_课程目标达成度.docx", "/Users/king/Downloads/测试学校_1_2021~2022第一学期_上学期《电力电子与电力传动》_课程目标达成度.pdf", 0);
+        File file = new File("/Users/king/Downloads/测试学校_1_2021~2022第一学期_上学期《电力电子与电力传动》_课程目标达成度.pdf");
+//        PdfUtil.addWaterMarkFullScreen(file, new String[]{"启明泰和_课程目标达成度测试水印"});
+        PdfUtil.waterMark(file, "启明泰和_课程目标达成度测试水印", "123");
+        return ResultUtil.ok(true);
+    }
 }
 }

+ 101 - 0
distributed-print/src/main/java/com/qmth/distributed/print/util/WordToPdfUtil.java

@@ -0,0 +1,101 @@
+package com.qmth.distributed.print.util;
+
+import com.aspose.words.*;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.ImportTemplateEnum;
+import com.qmth.teachcloud.common.util.FileUtil;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Objects;
+
+/**
+ * @Description: aspose pdf util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/7
+ */
+@Component
+public class WordToPdfUtil {
+    private final static Logger log = LoggerFactory.getLogger(WordToPdfUtil.class);
+
+    /**
+     * 获取license
+     *
+     * @return
+     */
+    private boolean getLicense() {
+        boolean result = false;
+        try {
+            License aposeLic = new License();
+            InputStream inputStream = FileUtil.getStream(ImportTemplateEnum.WORD_TO_PDF_LICENSE.getTemplateName());
+            aposeLic.setLicense(inputStream);
+            result = true;
+        } catch (Exception e) {
+            log.error("请求出错", e);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        }
+        return result;
+    }
+
+    /**
+     * document转pdf
+     *
+     * @param documentPath
+     * @param pdfPath
+     * @return
+     * @throws IOException
+     */
+    public File wordToPdf(String documentPath, String pdfPath, int paperSize) throws IOException {
+        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
+            throw ExceptionResultEnum.ERROR.exception("html转pdf失败,验证过期");
+        }
+        FileOutputStream os = null;
+        File file = null;
+        try {
+            long start = System.currentTimeMillis();
+            file = new File(pdfPath); //新建一个pdf文档
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+                file.createNewFile();
+            }
+            os = new FileOutputStream(file);
+            Document doc = new Document(documentPath); //Address是将要被转化的word文档
+            DocumentBuilder builder = new DocumentBuilder(doc);
+            PageSetup pageSetup = builder.getPageSetup();
+            pageSetup.setPaperSize(paperSize);
+            pageSetup.setVerticalAlignment(PageVerticalAlignment.TOP);
+            if (paperSize == PaperSize.A3) {
+                pageSetup.setOrientation(Orientation.PORTRAIT);
+            }
+            doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
+            long end = System.currentTimeMillis();
+            log.info("共耗时:" + ((end - start) / 1000.0) + "秒"); //转化用时
+        } catch (Exception e) {
+            log.error("请求出错", e);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            if (Objects.nonNull(os)) {
+                os.flush();
+                os.close();
+            }
+        }
+        return file;
+    }
+}

+ 14 - 0
distributed-print/src/main/resources/License.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<License>
+    <Data>
+        <Products>
+            <Product>Aspose.Total for Java</Product>
+            <Product>Aspose.Words for Java</Product>
+        </Products>
+        <EditionType>Enterprise</EditionType>
+        <SubscriptionExpiry>20991231</SubscriptionExpiry>
+        <LicenseExpiry>20991231</LicenseExpiry>
+        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
+    </Data>
+    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
+</License>

+ 5 - 5
distributed-print/src/main/resources/application.properties

@@ -10,11 +10,11 @@ server.tomcat.uri-encoding=UTF-8
 spring.application.name=teachcloud
 spring.application.name=teachcloud
 
 
 #\u6570\u636E\u6E90\u914D\u7F6E
 #\u6570\u636E\u6E90\u914D\u7F6E
-db.host=localhost
-db.port=3306
-db.name=teachcloud-v3.4.0-test
-db.username=root
-db.password=123456789
+db.host=192.168.10.136
+db.port=3307
+db.name=dps-v3.0.1-test
+db.username=dps_test
+db.password=dps_test
 
 
 #redis\u6570\u636E\u6E90\u914D\u7F6E
 #redis\u6570\u636E\u6E90\u914D\u7F6E
 com.qmth.redis.host=127.0.0.1
 com.qmth.redis.host=127.0.0.1

BIN
distributed-print/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar


+ 3 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/ImportTemplateEnum.java

@@ -23,7 +23,9 @@ public enum ImportTemplateEnum {
     TEMPLATE_OBJECTIVE_STRUCT("objectiveStruct.xlsx","客观题导入模板.xlsx"),
     TEMPLATE_OBJECTIVE_STRUCT("objectiveStruct.xlsx","客观题导入模板.xlsx"),
     TEMPLATE_SUBJECTIVE_STRUCT("subjectiveStruct.xlsx","主观题导入模板.xlsx"),
     TEMPLATE_SUBJECTIVE_STRUCT("subjectiveStruct.xlsx","主观题导入模板.xlsx"),
 
 
-    STATIC_COURSE_DEGREE_REPORT("course_degree_report.docx", "课程目标达成度");
+    STATIC_COURSE_DEGREE_REPORT("course_degree_report.docx", "课程目标达成度"),
+
+    WORD_TO_PDF_LICENSE("License.xml", "wordtopdf许可证");
 
 
     ImportTemplateEnum(String templateName, String fileName) {
     ImportTemplateEnum(String templateName, String fileName) {
         this.templateName = templateName;
         this.templateName = templateName;

+ 2 - 1
teachcloud-obe/src/main/resources/mapper/TCFinalScoreMapper.xml

@@ -35,6 +35,7 @@
 
 
     <select id="getCountByScoreRange" resultType="int">
     <select id="getCountByScoreRange" resultType="int">
         SELECT count(1) FROM t_c_final_score tcfs
         SELECT count(1) FROM t_c_final_score tcfs
+        join t_c_usual_score tcus on tcfs.course_id = tcus.course_id and tcfs.culture_program_id = tcus.culture_program_id and tcfs.student_code = tcus.student_code
         <where>
         <where>
             <if test="cultureProgramId != null and cultureProgramId != ''">
             <if test="cultureProgramId != null and cultureProgramId != ''">
                 and tcfs.culture_program_id = #{cultureProgramId}
                 and tcfs.culture_program_id = #{cultureProgramId}
@@ -43,7 +44,7 @@
                 and tcfs.course_id = #{courseId}
                 and tcfs.course_id = #{courseId}
             </if>
             </if>
                 and tcfs.score &gt;= #{start} and tcfs.score &lt;= #{end}
                 and tcfs.score &gt;= #{start} and tcfs.score &lt;= #{end}
-                and tcfs.enable = true
+                and tcfs.enable = true and tcus.enable = true
         </where>
         </where>
     </select>
     </select>