Browse Source

pdf转html,并实现鼠标移出内容隐藏

zoro 1 year ago
parent
commit
94839871be

+ 146 - 140
pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.2.1</version>
+        <version>2.7.14</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.shcd</groupId>
@@ -19,153 +19,159 @@
         <itext.version>8.0.2</itext.version>
     </properties>
     <dependencies>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-freemarker</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-freemarker</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.freemarker</groupId>
+        <artifactId>freemarker</artifactId>
+        <version>2.3.30</version>
+    </dependency>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+
+    <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ojdbc11</artifactId>
+        <scope>runtime</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.projectlombok</groupId>
+        <artifactId>lombok</artifactId>
+        <optional>true</optional>
+    </dependency>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-test</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <!--    pdfbox依赖-->
+    <dependency>
+        <groupId>org.apache.pdfbox</groupId>
+        <artifactId>pdfbox</artifactId>
+        <version>2.0.24</version>
+    </dependency>
+    <!--        itext依赖,但是只能打正规军,adobe适用,wps无效-->
+    <dependency>
+        <groupId>com.itextpdf</groupId>
+        <artifactId>itextpdf</artifactId>
+        <version>5.5.10</version>
+    </dependency>
 
-        <dependency>
-            <groupId>com.oracle.database.jdbc</groupId>
-            <artifactId>ojdbc11</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <!--    pdfbox依赖-->
-<!--        <dependency>-->
-<!--            <groupId>org.apache.pdfbox</groupId>-->
-<!--            <artifactId>pdfbox</artifactId>-->
-<!--            <version>2.0.24</version>-->
-<!--        </dependency>-->
-<!--        itext依赖,但是只能打正规军,adobe适用,wps无效-->
-        <dependency>
-            <groupId>com.itextpdf</groupId>
-            <artifactId>itextpdf</artifactId>
-            <version>5.5.10</version>
-        </dependency>
+    <dependency>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-component-annotations</artifactId>
+        <version>2.0.0</version>
+    </dependency>
+    <dependency>
+        <groupId>com.luhuiguo.bouncycastle</groupId>
+        <artifactId>bcprov-jdk15on</artifactId>
+        <version>1.70</version>
+    </dependency>
+    <dependency>
+        <groupId>com.itextpdf</groupId>
+        <artifactId>itext-asian</artifactId>
+        <version>5.2.0</version>
+    </dependency>
 
-        <dependency>
-            <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-component-annotations</artifactId>
-            <version>2.0.0</version>
-        </dependency>
-        <dependency>
-            <groupId>com.luhuiguo.bouncycastle</groupId>
-            <artifactId>bcprov-jdk15on</artifactId>
-            <version>1.70</version>
-        </dependency>
-        <dependency>
-            <groupId>com.itextpdf</groupId>
-            <artifactId>itext-asian</artifactId>
-            <version>5.2.0</version>
-        </dependency>
+    <!--        这个是最简单的加密方式,但是需要导入海量的包-->
+    <!-- always needed -->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>kernel</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; always needed &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>io</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; always needed &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>layout</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for forms &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>forms</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for PDF/A &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>pdfa</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for digital signatures &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>sign</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for barcodes &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>barcodes</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for Asian fonts &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>font-asian</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        &lt;!&ndash; only needed for hyphenation &ndash;&gt;-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>hyph</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>bouncy-castle-adapter</artifactId>-->
+    <!--            <version>${itext.version}</version>-->
+    <!--        </dependency>-->
 
-<!--        这个是最简单的加密方式,但是需要导入海量的包-->
-        <!-- always needed -->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>kernel</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; always needed &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>io</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; always needed &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>layout</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for forms &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>forms</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for PDF/A &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>pdfa</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for digital signatures &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>sign</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for barcodes &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>barcodes</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for Asian fonts &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>font-asian</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        &lt;!&ndash; only needed for hyphenation &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>hyph</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>bouncy-castle-adapter</artifactId>-->
-<!--            <version>${itext.version}</version>-->
-<!--        </dependency>-->
 
+    <!--        <dependency>-->
+    <!--            <groupId>com.itextpdf</groupId>-->
+    <!--            <artifactId>itext7-core</artifactId>-->
+    <!--            <version>8.0.2</version>-->
+    <!--        </dependency>-->
+    <!--                Free Spire依赖 免费版会添加水印不能用-->
+    <!--        <dependency>-->
+    <!--            <groupId>e-iceblue</groupId>-->
+    <!--            <artifactId>spire.pdf</artifactId>-->
+    <!--            <version>10.1.5</version>-->
+    <!--        </dependency>-->
 
-<!--        <dependency>-->
-<!--            <groupId>com.itextpdf</groupId>-->
-<!--            <artifactId>itext7-core</artifactId>-->
-<!--            <version>8.0.2</version>-->
-<!--        </dependency>-->
-        <!--        Free Spire依赖-->
-<!--        <dependency>-->
-<!--            <groupId>e-iceblue</groupId>-->
-<!--            <artifactId>spire.pdf</artifactId>-->
-<!--            <version>10.1.5</version>-->
-<!--        </dependency>-->
+    <!--        <dependency>-->
+    <!--            <groupId>e-iceblue</groupId>-->
+    <!--            <artifactId>spire.pdf.free</artifactId>-->
+    <!--            <version>3.9.0</version>-->
+    <!--        </dependency>-->
 
-<!--        <dependency>-->
-<!--            <groupId>e-iceblue</groupId>-->
-<!--            <artifactId>spire.pdf.free</artifactId>-->
-<!--            <version>3.9.0</version>-->
-<!--        </dependency>-->
 
-<!--        <dependency>-->
-<!--            <groupId>javax.xml.bind</groupId>-->
-<!--            <artifactId>jaxb-api</artifactId>-->
-<!--            <version>2.3.1</version>-->
-<!--        </dependency>-->
-    </dependencies>
+    <!--        <dependency>-->
+    <!--            <groupId>javax.xml.bind</groupId>-->
+    <!--            <artifactId>jaxb-api</artifactId>-->
+    <!--            <version>2.3.1</version>-->
+    <!--        </dependency>-->
+        </dependencies>
 
-<!--    <repositories>-->
-<!--        <repository>-->
-<!--            <id>com.e-iceblue</id>-->
-<!--            <name>e-iceblue</name>-->
-<!--            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>-->
-<!--        </repository>-->
-<!--    </repositories>-->
+    <!--    <repositories>-->
+    <!--        <repository>-->
+    <!--            <id>com.e-iceblue</id>-->
+    <!--            <name>e-iceblue</name>-->
+    <!--            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>-->
+    <!--        </repository>-->
+    <!--    </repositories>-->
 
 
     <build>

+ 30 - 0
src/main/java/com/shcd/ghjg_pdf/controller/PdfController.java

@@ -0,0 +1,30 @@
+package com.shcd.ghjg_pdf.controller;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.HashMap;
+
+@Controller
+@CrossOrigin
+@RequestMapping("/pdf")
+public class PdfController {
+
+//    @GetMapping("test")
+//    public  String test() throws Exception {
+//        HashMap<String, String> map = new HashMap<>();
+//        //map.put("title","test");
+//        map.put("dirPath","E:\\pdf\\DM8_DIsql使用手册_水印.pdf");
+//        String filename = System.currentTimeMillis() + ".html";
+//        File file = new File("E:\\pdf\\" + filename);
+//        FileWriter fileWriter = new FileWriter(file);
+//        Configuration configuration = new Configuration();
+//        Template template = configuration.getTemplate("template.ftl");
+//        template.process(map, fileWriter);
+//        return "template";
+//    }
+}

+ 20 - 7
src/main/java/com/shcd/ghjg_pdf/service/impl/PDFServiceFreeSpire.java

@@ -2,10 +2,16 @@
 //
 //import com.spire.pdf.FileFormat;
 //import com.spire.pdf.PdfDocument;
-//import com.spire.pdf.actions.PdfJavaScriptAction;
+//import com.spire.pdf.PdfPageBase;
+//import com.spire.pdf.graphics.PdfBrush;
+//import com.spire.pdf.graphics.PdfBrushes;
+//import com.spire.pdf.graphics.PdfFontBase;
+//import com.spire.pdf.graphics.PdfTrueTypeFont;
 //import jakarta.annotation.PostConstruct;
 //import org.springframework.stereotype.Component;
 //
+//import java.awt.*;
+//
 //@Component
 //public class PDFServiceFreeSpire {
 //    //不可使用,会自动增加水印
@@ -16,17 +22,24 @@
 //
 //        //加载一个PDF文档
 //        doc.loadFromFile("E:\\pdf\\DM8_DIsql使用手册.pdf");
-//
+//        PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("宋体", Font.PLAIN, 50));
+//        for (int i = 0; i < doc.getPages().getCount(); i++) {
+//            PdfPageBase pageBase = doc.getPages().get(i);
+//            pageBase.getCanvas().setTransparency(0.8);
+//            pageBase.getCanvas().translateTransform(pageBase.getCanvas().getSize().getWidth()/2,pageBase.getCanvas().getSize().getHeight()/2);
+//            pageBase.getCanvas().rotateTransform(-45);
+//            pageBase.getCanvas().drawString("test",font, PdfBrushes.getDarkBlue(),0,0);
+//        }
 //        //通过JavaScript设置过期时间,过期警告信息并关闭文档
-//        String javaScript =
-//                "app.alert('该文档已过期,请联系我们获取新文档',1);"
-//                + "this.closeDoc(); ";
+////        String javaScript =
+////                "app.alert('该文档已过期,请联系我们获取新文档',1);"
+////                + "this.closeDoc(); ";
 //
 //        //根据JS创建PdfJavaScriptAction
-//        PdfJavaScriptAction js = new PdfJavaScriptAction(javaScript);
+//        //PdfJavaScriptAction js = new PdfJavaScriptAction(javaScript);
 //
 //        //将PdfJavaScriptAction设置为文档打开后的动作
-//        doc.setAfterOpenAction(js);
+//        //doc.setAfterOpenAction(js);
 //
 //        //保存文档
 //        doc.saveToFile("E:\\pdf\\test.pdf", FileFormat.PDF);

+ 23 - 37
src/main/java/com/shcd/ghjg_pdf/service/impl/PDFServiceITextImpl.java

@@ -5,9 +5,12 @@ package com.shcd.ghjg_pdf.service.impl;
 //import com.itextpdf.kernel.pdf.EncryptionProperties;
 //import com.itextpdf.kernel.pdf.PdfEncryptor;
 //import com.itextpdf.kernel.pdf.PdfReader;
+
 import com.itextpdf.text.BaseColor;
-import com.itextpdf.text.pdf.*;
-import jakarta.annotation.PostConstruct;
+import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfContentByte;
+import com.itextpdf.text.pdf.PdfReader;
+import com.itextpdf.text.pdf.PdfStamper;
 import org.springframework.stereotype.Component;
 
 import java.nio.file.Files;
@@ -15,7 +18,7 @@ import java.nio.file.Paths;
 
 @Component
 public class PDFServiceITextImpl {
-    @PostConstruct
+    //@PostConstruct
     public void pdfEncode() throws Exception {
         PdfReader pdfReader = new PdfReader("E:\\pdf\\DM8_DIsql使用手册.pdf");
         PdfStamper pdfStamper = new PdfStamper(pdfReader, Files.newOutputStream(Paths.get("E:\\pdf\\encrypted.pdf")));
@@ -30,40 +33,23 @@ public class PDFServiceITextImpl {
         }
         pdfStamper.close();
         pdfReader.close();
+
         PdfReader reader = new PdfReader("E:\\pdf\\encrypted.pdf");
-        PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get("E:\\pdf\\encryptedwithJS.pdf")));
-        //设置密码
-        stamper.setEncryption("123456".getBytes(), "123457".getBytes(), PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_40);
-        //String javaScript = "app.alert('Hello World');";
-        String javaScript = "var rightNow = new Date();"
-                + "var endDate = new Date('2024/1/14 08:09:10');"
-                + "if(rightNow.getTime() > endDate.getTime()){"
-                + "app.alert('该文档已过期,请联系我们获取新文档',1);"
-                + "this.closeDoc();}";
-        //设置打开文件时的操作
-        for (int i = 1; i < reader.getNumberOfPages(); i++) {
-            stamper.setPageAction(PdfWriter.PAGE_OPEN,PdfAction.javaScript(javaScript,stamper.getWriter()),i);
-        }
-        stamper.flush();
-        stamper.close();
-        reader.close();
-        //Files.delete(Paths.get("E:\\pdf\\DM8_DIsql使用手册_encrypted.pdf"));
-        /*Document document = new Document();
-        document.open();
-        PdfReader pdfReader = new PdfReader("E:\\pdf\\DM8_DIsql使用手册.pdf");
-        PdfStamper pdfStamper = new PdfStamper(pdfReader, Files.newOutputStream(Paths.get("E:\\pdf\\DM8_DIsql使用手册_encrypted.pdf")));
-        pdfStamper.setEncryption("123456".getBytes(), "123457".getBytes(), PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_40);
-        pdfStamper.close();
-        pdfReader.close();*/
-//                try {
-//                    // 为PDF文档添加密码和过期时间
-//                    PdfReader reader = new PdfReader("E:\\pdf\\DM8_DIsql使用手册.pdf");
-//                    EncryptionProperties encryptionProperties = new EncryptionProperties();
-//                    encryptionProperties.setStandardEncryption("123456".getBytes(), "123457".getBytes(), EncryptionConstants.ALLOW_PRINTING,EncryptionConstants.ENCRYPTION_AES_128);
-//                    PdfEncryptor.encrypt(reader, Files.newOutputStream(Paths.get("E:\\pdf\\1.pdf")),encryptionProperties);
-//                    reader.close();
-//                } catch (Exception e) {
-//                    e.printStackTrace();
-//                }
+//        PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get("E:\\pdf\\encryptedwithJS.pdf")));
+//        //设置密码
+//        stamper.setEncryption("123456".getBytes(), "123457".getBytes(), PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_40);
+//        //String javaScript = "app.alert('Hello World');";
+//        String javaScript = "var rightNow = new Date();"
+//                + "var endDate = new Date('2024/1/14 08:09:10');"
+//                + "if(rightNow.getTime() > endDate.getTime()){"
+//                + "app.alert('该文档已过期,请联系我们获取新文档',1);"
+//                + "this.closeDoc();}";
+//        //设置打开文件时的操作
+//        for (int i = 1; i < reader.getNumberOfPages(); i++) {
+//            stamper.setPageAction(PdfWriter.PAGE_OPEN,PdfAction.javaScript(javaScript,stamper.getWriter()),i);
+//        }
+//        stamper.flush();
+//        stamper.close();
+//        reader.close();
             }
 }

+ 176 - 0
src/main/java/com/shcd/ghjg_pdf/service/impl/PdfConvertHtmlUtil.java

@@ -0,0 +1,176 @@
+package com.shcd.ghjg_pdf.service.impl;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+
+/**
+ * PDF文档转HTML文档
+ * @author LXW
+ * @date 2020/6/17 16:45
+ */
+public class PdfConvertHtmlUtil {
+    /**
+     * 日志对象
+     */
+    private static Logger logger = LoggerFactory.getLogger(PdfConvertHtmlUtil.class);
+
+    /**
+     * PDF文档流转Png
+     * @param pdfFileInputStream
+     * @return BufferedImage
+     */
+    public static BufferedImage pdfStreamToPng(InputStream pdfFileInputStream){
+        PDDocument doc = null;
+        PDFRenderer renderer = null;
+        try {
+            doc = PDDocument.load(pdfFileInputStream);
+            renderer = new PDFRenderer(doc);
+            int pageCount = doc.getNumberOfPages();
+            BufferedImage image = null;
+            for (int i = 0; i < pageCount; i++) {
+                if (image != null) {
+                    image = combineBufferedImages(image, renderer.renderImageWithDPI(i, 144));
+                }
+
+                if (i == 0) {
+                    image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
+                }
+                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
+            }
+            return combineBufferedImages(image);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }finally {
+            try {
+                if(doc != null){doc.close();}
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     *BufferedImage拼接处理,添加分割线
+     * @param images
+     * @return BufferedImage
+     */
+    public static BufferedImage combineBufferedImages(BufferedImage... images) {
+        int height = 0;
+        int width = 0;
+        for (BufferedImage image : images) {
+            //height += Math.max(height, image.getHeight());
+            height += image.getHeight();
+            width = image.getWidth();
+        }
+        BufferedImage combo = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g2 = combo.createGraphics();
+        int x = 0;
+        int y = 0;
+        for (BufferedImage image : images) {
+            //int y = (height - image.getHeight()) / 2;
+            g2.setStroke(new BasicStroke(2.0f));// 线条粗细
+            g2.setColor(new Color(193, 193, 193));// 线条颜色
+            g2.drawLine(x, y, width, y);// 线条起点及终点位置
+
+            g2.drawImage(image, x, y, null);
+            //x += image.getWidth();
+            y += image.getHeight();
+
+        }
+        return combo;
+    }
+    /**
+     * 通过Base64创建HTML文件并输出html文件
+     * @param base64
+     * @param htmlPath html保存路径
+     */
+    public static void createHtmlByBase64(String base64,String htmlPath) {
+        StringBuilder stringHtml = new StringBuilder();
+        PrintStream printStream = null;
+        try {
+            // 打开文件
+            printStream = new PrintStream(new FileOutputStream(htmlPath));
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        // 输入HTML文件内容
+        stringHtml.append("<html><head>");
+        stringHtml.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+        stringHtml.append("<title></title>");
+        stringHtml.append("</head>");
+        stringHtml.append(
+                "<body style=\"\r\n" + "    text-align: center;\r\n" + "    background-color: #C1C1C1;\r\n" + "\">");
+        stringHtml.append("<div id = \"content\">");
+        stringHtml.append("<img src=\"data:image/png;base64,").append(base64).append("\" />");
+        stringHtml.append("<a name=\"head\" style=\"position:absolute;top:0px;\"></a>");
+        //添加锚点用于返回首页
+        stringHtml.append("<a style=\"position:fixed;bottom:10px;right:10px\" href=\"#head\">回到首页</a>");
+        stringHtml.append("</div>");
+        stringHtml.append("<script>\n" +
+                "    function addEvent(obj, evt, fn) {\n" +
+                "      if (obj.addEventListener) {\n" +
+                "        obj.addEventListener(evt, fn, false);\n" +
+                "      }\n" +
+                "      else if (obj.attachEvent) {\n" +
+                "        obj.attachEvent(\"on\" + evt, fn);\n" +
+                "      }\n" +
+                "    }\n" +
+                "    addEvent(window,\"load\",function(e) {\n" +
+                "      addEvent(document,\"mouseout\", function(e) {\n" +
+                "          document.getElementById(\"content\").style.display = 'none'\n" +
+                "      });\n" +
+                "\n" +
+                "      addEvent(document,\"mouseover\", function(e) {\n" +
+                "          console.log(\"456\")\n" +
+                "          document.getElementById(\"content\").style.display = 'block'\n" +
+                "      });\n" +
+                "    });\n" +
+                "  </script>");
+        stringHtml.append("</body></html>");
+
+        try {
+            // 将HTML文件内容写入文件中
+            printStream.println(stringHtml.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }finally {
+            if(printStream != null){printStream.close();}
+        }
+
+    }
+
+    /**
+     * bufferedImage 转为 base64编码
+     * @param bufferedImage
+     * @return
+     */
+    public static String bufferedImageToBase64(BufferedImage bufferedImage) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        String png_base64 = "";
+        try {
+            ImageIO.write(bufferedImage, "png", byteArrayOutputStream);// 写入流中
+            byte[] bytes = byteArrayOutputStream.toByteArray();// 转换成字节
+            BASE64Encoder encoder = new BASE64Encoder();
+            // 转换成base64串 删除 \r\n
+            png_base64 = encoder.encodeBuffer(bytes).trim()
+                    .replaceAll("\n", "")
+                    .replaceAll("\r", "");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return png_base64;
+    }
+
+
+}
+

+ 35 - 0
src/main/java/com/shcd/ghjg_pdf/service/impl/test.java

@@ -0,0 +1,35 @@
+package com.shcd.ghjg_pdf.service.impl;
+
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.awt.image.BufferedImage;
+import java.io.*;
+
+import static com.shcd.ghjg_pdf.service.impl.PdfConvertHtmlUtil.*;
+
+@Component
+public class test {
+    @PostConstruct
+    public void test(){
+        File file = new File("E:\\pdf\\encrypted.pdf");
+        String htmlPath = "E:\\pdf\\encrypted.html";
+        InputStream inputStream = null;
+        BufferedImage bufferedImage = null;
+        try {
+            inputStream = new FileInputStream(file);
+            bufferedImage = pdfStreamToPng(inputStream);
+            String base64_png = bufferedImageToBase64(bufferedImage);
+            createHtmlByBase64(base64_png,htmlPath);
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }finally {
+            try {
+                if(inputStream != null){inputStream.close();}
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 7 - 0
src/main/resources/application.properties

@@ -3,3 +3,10 @@ spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
 spring.datasource.name=ghjg_basics
 spring.datasource.password=GHJG@123
 spring.datasource.url=jdbc:oracle:thin:@10.114.4.56:shhwdb
+spring.freemarker.template-loader-path=classpath:/templates/
+spring.freemarker.charset=UTF-8
+spring.freemarker.suffix=.ftl
+spring.freemarker.content-type=text/html
+spring.freemarker.enabled=true
+spring.freemarker.settings.classic_compatible=true
+spring.groovy.template.resource-loader-path=classpath:/templates/

+ 11 - 0
src/main/resources/templates/template.ftl

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>test</title>
+</head>
+<body>
+<#--    <embed src = "E:\\pdf\\DM8_DIsql使用手册_水印.pdf" width = 500 height = 500 type = "application/pdf">-->
+</body>
+<#include "${dirPath}">
+</html>