Browse Source

Merge remote-tracking branch 'origin/master' into 20210916

# Conflicts:
#	README.md
#	pom.xml
#	src/main/java/com/gz/scheduled/ScanArchiveFileScheduled.java
#	src/main/java/com/gz/service/statistics/impl/SelectStatisticsServiceImpl.java
#	src/main/java/com/gz/utils/UnitUtils.java
刘嘉伟 3 years ago
parent
commit
30519d2c02

+ 1 - 0
README.md

@@ -109,6 +109,7 @@ ______
 
 
 > + 附件:南京NO.2018G46地块(奥特佳项目)规划设计方案
 > + 附件:南京NO.2018G46地块(奥特佳项目)规划设计方案
 > + 关于对建邺区江东中路377号南京金融城一期项目地下室进行确认的复函
 > + 关于对建邺区江东中路377号南京金融城一期项目地下室进行确认的复函
+> + 卷内目录档号Excel处理公式:`=CONCAT(A2,"-",IF(COUNTIF(G2,"*-*"),TEXT(LEFT(G2,FIND("-",G2)-1),"0000"),TEXT(G2,"0000")))`
 
 
 > Excel卷内目录档号公式   `=A2&"-"&TEXT(IF(ISNUMBER(FIND("-",G2,1)),LEFT(G2,FIND("-",G2,1) - 1),G2),"0000")`
 > Excel卷内目录档号公式   `=A2&"-"&TEXT(IF(ISNUMBER(FIND("-",G2,1)),LEFT(G2,FIND("-",G2,1) - 1),G2),"0000")`
 
 

+ 63 - 52
pom.xml

@@ -159,6 +159,17 @@
             <artifactId>spire.pdf.free</artifactId>
             <artifactId>spire.pdf.free</artifactId>
             <version>3.9.0</version>
             <version>3.9.0</version>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.lowagie</groupId>
+            <artifactId>itext</artifactId>
+            <version>4.2.1</version>
+        </dependency>
     </dependencies>
     </dependencies>
 
 
     <build>
     <build>
@@ -171,60 +182,60 @@
                 </configuration>
                 </configuration>
             </plugin>
             </plugin>
 
 
-            <plugin>
-                <groupId>cn.smallbun.screw</groupId>
-                <artifactId>screw-maven-plugin</artifactId>
-                <version>1.0.3</version>
-                <dependencies>
-                    <!-- HikariCP -->
-                    <dependency>
-                        <groupId>com.zaxxer</groupId>
-                        <artifactId>HikariCP</artifactId>
-                        <version>3.4.5</version>
-                    </dependency>
-                    <!--mysql driver-->
-                    <dependency>
-                        <groupId>mysql</groupId>
-                        <artifactId>mysql-connector-java</artifactId>
-                        <version>8.0.20</version>
-                    </dependency>
-                </dependencies>
-                <configuration>
-                    <!--username-->
-                    <username>root</username>
-                    <!--password-->
-                    <password>abcd123456!@#</password>
-                    <!--driver-->
-                    <driverClassName>com.mysql.cj.jdbc.Driver</driverClassName>
-                    <!--jdbc url-->
-                    <jdbcUrl>
-                        <![CDATA[jdbc:mysql://115.159.38.225:3306/cmsga?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8]]></jdbcUrl>
-                    <!--生成文件类型-->
-                    <fileType>WORD</fileType>
-                    <!--打开文件输出目录-->
-                    <openOutputDir>false</openOutputDir>
-                    <!--生成模板-->
-                    <produceType>freemarker</produceType>
-                    <!--文档名称 为空时:将采用[数据库名称-描述-版本号]作为文档名称-->
-                    <!--                    <fileName>111</fileName>-->
-                    <!--描述-->
-                    <description>数据库文档生成</description>
-                    <!--版本-->
-                    <version>${project.version}</version>
-                    <!--标题-->
-                    <title>数据库文档</title>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>compile</phase>
-                        <!--                        <goals>-->
-                        <!--                            <goal>run</goal>-->
-                        <!--                        </goals>-->
-                    </execution>
-                </executions>
-            </plugin>
+<!--            <plugin>-->
+<!--                <groupId>cn.smallbun.screw</groupId>-->
+<!--                <artifactId>screw-maven-plugin</artifactId>-->
+<!--                <version>1.0.3</version>-->
+<!--                <dependencies>-->
+<!--                    &lt;!&ndash; HikariCP &ndash;&gt;-->
+<!--                    <dependency>-->
+<!--                        <groupId>com.zaxxer</groupId>-->
+<!--                        <artifactId>HikariCP</artifactId>-->
+<!--                        <version>3.4.5</version>-->
+<!--                    </dependency>-->
+<!--                    &lt;!&ndash;mysql driver&ndash;&gt;-->
+<!--                    <dependency>-->
+<!--                        <groupId>mysql</groupId>-->
+<!--                        <artifactId>mysql-connector-java</artifactId>-->
+<!--                        <version>8.0.20</version>-->
+<!--                    </dependency>-->
+<!--                </dependencies>-->
+<!--                <configuration>-->
+<!--                    &lt;!&ndash;username&ndash;&gt;-->
+<!--                    <username>root</username>-->
+<!--                    &lt;!&ndash;password&ndash;&gt;-->
+<!--                    <password>abcd123456!@#</password>-->
+<!--                    &lt;!&ndash;driver&ndash;&gt;-->
+<!--                    <driverClassName>com.mysql.cj.jdbc.Driver</driverClassName>-->
+<!--                    &lt;!&ndash;jdbc url&ndash;&gt;-->
+<!--                    <jdbcUrl><![CDATA[jdbc:mysql://115.159.38.225:3306/guihua_archives?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8]]></jdbcUrl>-->
+<!--                    &lt;!&ndash;生成文件类型&ndash;&gt;-->
+<!--                    <fileType>WORD</fileType>-->
+<!--                    &lt;!&ndash;打开文件输出目录&ndash;&gt;-->
+<!--                    <openOutputDir>false</openOutputDir>-->
+<!--                    &lt;!&ndash;生成模板&ndash;&gt;-->
+<!--                    <produceType>freemarker</produceType>-->
+<!--                    &lt;!&ndash;文档名称 为空时:将采用[数据库名称-描述-版本号]作为文档名称&ndash;&gt;-->
+<!--&lt;!&ndash;                    <fileName>111</fileName>&ndash;&gt;-->
+<!--                    &lt;!&ndash;描述&ndash;&gt;-->
+<!--                    <description>数据库文档生成</description>-->
+<!--                    &lt;!&ndash;版本&ndash;&gt;-->
+<!--                    <version>${project.version}</version>-->
+<!--                    &lt;!&ndash;标题&ndash;&gt;-->
+<!--                    <title>数据库文档</title>-->
+<!--                </configuration>-->
+<!--                <executions>-->
+<!--                    <execution>-->
+<!--                        <phase>compile</phase>-->
+<!--                        <goals>-->
+<!--                            <goal>run</goal>-->
+<!--                        </goals>-->
+<!--                    </execution>-->
+<!--                </executions>-->
+<!--            </plugin>-->
         </plugins>
         </plugins>
     </build>
     </build>
 
 
 
 
+
 </project>
 </project>

+ 244 - 0
py/档案数据.py

@@ -0,0 +1,244 @@
+import json
+import os
+from concurrent.futures import ThreadPoolExecutor
+from urllib.parse import urlencode
+from urllib.request import Request
+from urllib.request import urlopen
+import re
+import time
+
+# 请求地址
+base_url = 'http://192.168.1.153:3000'
+
+# 数据存储目录
+base_folder = 'H:\jy'
+
+# 线程池最大线程
+thread_count = 3
+
+# 用户id (目前没发现有啥用,不用改)
+user_id = 28
+
+headers = {
+    # 'User-Agent': UserAgent().chrome
+    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
+    # cookie模拟登录 过期了需要到网页登录抓取cookie替换这里
+    'Cookie': '_iChad_session=BAh7CCIPc2Vzc2lvbl9pZCIlOWExYTE5MGZlZDE1YTRmZGMxMjY4MDRmZTQxN2JmNjciGXdhcmRlbi51c2VyLnVzZXIua2V5WwgiCVVzZXJbBmkhIiIkMmEkMTAkUXRJMkkyNTQ0SGJoRkVCOHo2d0REdSIQX2NzcmZfdG9rZW4iMWRXQkRhL2NjbEdmL3k4ZWZrYXgzVE1rWksrdkxhL0FzclhPQWxSVkRXRmc9--8bf8e98234e136cc2512da7e36b33bc1580fa5da'
+}
+
+rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'
+
+
+# 写入到文件
+def save_to_file(file_name, contents):
+    fh = open(file_name, 'wb+')
+    contents = contents.encode('utf-8')
+    fh.write(contents)
+    fh.close()
+    print('写入数据到【' + file_name + '】完成')
+
+
+# 创建目录
+def mkdir(file_name):
+    folder = os.path.exists(file_name)
+    if not folder:
+        os.makedirs(file_name)
+        print('创建目录' + file_name)
+    else:
+        print(file_name + '目录已经存在,跳过创建')
+
+
+# 下载到本地
+def download(url, file_path):
+    print('开始下载' + url)
+    f = urlopen(url)
+    data = f.read()
+    with open(file_path, "wb") as code:
+        code.write(data)
+
+
+# 发送get请求
+def get(url):
+    # 创建请求
+    request = Request(url, headers=headers)
+    # 发起请求
+    response = urlopen(request)
+    # 读取响应内容
+    response_str = response.read()
+    # 转换unicode
+    # response_str = response_str.decode().encode("utf-8").decode("unicode_escape")
+    response_str = response_str.decode()
+    # 修正返回结果为json格式
+    response_str = response_str.replace('results', '"results"')
+    response_str = response_str.replace('rows', '"rows"')
+    return response_str
+
+
+# 发送post请求
+def post(url, body):
+    # 设置post为formdata提交方式
+    headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
+    body = urlencode(body)
+    data = body.encode('utf-8')
+    request = Request(url, headers=headers, data=data, method='POST')
+    response = urlopen(request)
+    response_str = response.read()
+    return response_str
+
+
+# 获取所有的档案类型
+def getArchiveTypes():
+    api_path = '/desktop/get_dalb_print_grid'
+    params = {
+        '_dc': 1637722889393,
+        'userid': user_id,
+        'page': 1,
+        'start': 0,
+        'limit': 99999
+    }
+    finally_url = base_url + api_path + f'?' + urlencode(params)
+    result = get(finally_url)
+    response_obj = json.loads(result)
+    for index, type in enumerate(response_obj['rows']):
+        if index < 3:
+            print('跳过' + type['lbmc'])
+            continue;
+        print('开始爬取【' + type['lbmc'] + '】数据')
+        type_folder = base_folder + '\\' + str(type['id']) + '_' + type['lbmc']
+        mkdir(type_folder)
+        getArchives(type['id'], type_folder)
+    # with ThreadPoolExecutor(max_workers=thread_count) as t:
+    #     for type in response_obj['rows']:
+    #         print('开始爬取【' + type['lbmc'] + '】数据')
+    #         type_folder = base_folder + '\\' + str(type['id']) + '_' + type['lbmc']
+    #         mkdir(type_folder)
+    #         t.submit(getArchives, type['id'], type_folder)
+
+
+# 根据档案类型获取所有的档案数据
+def getArchives(type, folder):
+    api_path = '/desktop/archive_query_jygl'
+    for pageIndex in range(5):
+        params = {
+            "dalb": type,
+            "userid": user_id,
+            "page": pageIndex + 1,
+            "start": pageIndex * 1000,
+            "limit": 1000,
+        }
+        finally_url = base_url + api_path + f'?' + urlencode(params)
+        result = get(finally_url)
+        response_obj = json.loads(result)
+        print('读取该类型下数据完成,共有' + str(response_obj['results']) + '条数据')
+        for index, row in enumerate(response_obj['rows']):
+            # 当前这条数据的文件夹
+            tm = row['tm']
+            tm = re.sub(rstr, "_", tm)
+            data_folder = folder + '\\' + str(index + (pageIndex * 1000)) + '_' + tm
+            mkdir(data_folder)
+            getArchiveDetails(row, data_folder)
+        # with ThreadPoolExecutor(max_workers=thread_count) as t:
+        #     for row in response_obj['rows']:
+        #         # 当前这条数据的文件夹
+        #         data_folder = folder + '\\' + row['tm']
+        #         mkdir(data_folder)
+        #         # getArchiveDetails(row, data_folder)
+        #         t.submit(getArchiveDetails, row, data_folder)
+
+
+# 根据id获取详细信息
+def getArchiveDetails(row, data_folder):
+    print('开始读取【' + row['tm'] + '】详细信息')
+    local_json_path = data_folder + '\\' + 'data.json'
+    if not os.path.exists(local_json_path):
+        api_path = '/desktop/get_archivebyid'
+        body = {
+            'id': row['id'],
+            'dh': row['dh'],
+            'userid': user_id,
+        }
+        finally_url = base_url + api_path
+        result = post(finally_url, body)
+        # 保存数据到文件
+        save_to_file(local_json_path, result.decode())
+    else:
+        print(f'{row["tm"]} json数据已经存在,跳过保存')
+    # 获取卷内目录数据
+    getArchiveInner(row['id'], data_folder)
+    print('开始下载【' + row['tm'] + '】的文件')
+    getArchiveFile(row['dh'], data_folder)
+
+
+# 获取档案文件集合
+def getArchiveFile(dh, data_folder):
+    api_path = '/desktop/get_yx_tree?_dc=1637737132431'
+    body = {
+        'node': 'root',
+        'dh': dh
+    }
+    finally_url = base_url + api_path
+    result = post(finally_url, body)
+    result = result.decode()
+    result = result.replace('\'', '\"')
+    response_obj = json.loads(result)
+    for file in response_obj:
+        for index, file_item in enumerate(file['children']):
+            id = file_item['id']
+            file_id = id[:str(id).index('|')]
+            file_name = file_item['text']
+            cs = 0
+            while cs < 3:
+                try:
+                    getArchiveFileDownloadUrl(file_id, data_folder, str(index) + file_name)
+                    cs = 3  # 跳出循环
+                except BaseException:
+                    print(f'{file_name}出现错误休息3秒 再试')
+                    cs += 1  # 记录出错次数
+                    time.sleep(3)
+    # with ThreadPoolExecutor(max_workers=thread_count) as t:
+    #     for file in response_obj:
+    #         for file_item in file['children']:
+    #             id = file_item['id']
+    #             file_id = id[:str(id).index('|')]
+    #             file_name = file_item['text']
+    #             t.submit(getArchiveFileDownloadUrl, file_id, data_folder, file_name)
+
+
+# 获取文件下载地址
+def getArchiveFileDownloadUrl(file_id, data_folder, file_name):
+    api_path = '/desktop/get_timage_from_db'
+    local_path = data_folder + '\\' + file_name + '.jpg'
+    if os.path.exists(local_path):
+        print(file_name + '文件已经下载过了,跳过')
+        return
+    body = {
+        'gid': file_id,
+        'userid': user_id
+    }
+    finally_url = base_url + api_path
+    response_str = post(finally_url, body)
+    img_path = response_str.decode().replace('assets/./', 'assets/')
+    download(base_url + img_path, local_path)
+
+
+# 获取卷内目录数据
+def getArchiveInner(archive_id, data_folder):
+    print('开始读取' + str(archive_id) + '的卷内目录数据')
+    inner_json_path = data_folder + '\\' + 'inner.json'
+    if not os.path.exists(inner_json_path):
+        api_path = '/desktop/get_document'
+        params = {
+            "query": archive_id,
+            "page": 1,
+            "start": 0,
+            "limit": 99999,
+        }
+        finally_url = base_url + api_path + f'?' + urlencode(params)
+        response_str = get(finally_url)
+        save_to_file(data_folder + '\\' + 'inner.json', response_str)
+    else:
+        print(f'{archive_id} 卷内目录json数据已经存在 跳过保存')
+
+
+if __name__ == '__main__':
+    getArchiveTypes()

+ 0 - 1
src/main/java/com/gz/config/MountArchiveFileConfig.java

@@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 
 
-import javax.annotation.PostConstruct;
 import java.io.File;
 import java.io.File;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ExecutorService;

+ 0 - 2
src/main/java/com/gz/scheduled/ScanArchiveFileScheduled.java

@@ -4,10 +4,8 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import com.gz.config.MountArchiveFileConfig;
 import com.gz.config.MountArchiveFileConfig;
 import com.gz.core.exception.BusinessException;
 import com.gz.core.exception.BusinessException;
-import com.gz.mapper.archive.ArchiveFileMapper;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.frameworkset.spi.annotations.Component;
 import org.frameworkset.spi.annotations.Component;
-import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Profile;
 import org.springframework.context.annotation.Profile;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.annotation.Scheduled;

+ 5 - 7
src/main/java/com/gz/service/statistics/impl/SelectStatisticsServiceImpl.java

@@ -4,10 +4,9 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.RuntimeUtil;
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNodeConfig;
+import cn.hutool.core.lang.tree.TreeUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ReUtil;
 import cn.hutool.core.util.ReUtil;
 import cn.hutool.core.util.RuntimeUtil;
 import cn.hutool.core.util.RuntimeUtil;
@@ -20,6 +19,7 @@ import com.gz.dto.borrow.ArchiveBorrowDTO;
 import com.gz.dto.system.ArchivesTreeDTO;
 import com.gz.dto.system.ArchivesTreeDTO;
 import com.gz.mapper.borrow.ArchiveBorrowMapper;
 import com.gz.mapper.borrow.ArchiveBorrowMapper;
 import com.gz.mapper.statistics.SelectStatisticsMapper;
 import com.gz.mapper.statistics.SelectStatisticsMapper;
+import com.gz.mapper.system.ArchivesTreeMapper;
 import com.gz.rvo.statistics.ArchiveStatisticsRVO;
 import com.gz.rvo.statistics.ArchiveStatisticsRVO;
 import com.gz.rvo.statistics.ArchiveYearStatisticsRVO;
 import com.gz.rvo.statistics.ArchiveYearStatisticsRVO;
 import com.gz.rvo.statistics.BorrowStatisticsRVO;
 import com.gz.rvo.statistics.BorrowStatisticsRVO;
@@ -27,7 +27,6 @@ import com.gz.service.statistics.SelectStatisticsService;
 import com.gz.service.system.ArchivesTreeService;
 import com.gz.service.system.ArchivesTreeService;
 import com.gz.service.system.impl.AuthServiceImpl;
 import com.gz.service.system.impl.AuthServiceImpl;
 import com.gz.utils.JwtUtils;
 import com.gz.utils.JwtUtils;
-import com.gz.utils.UnitUtils;
 import com.gz.vo.statistics.StatisticsVO;
 import com.gz.vo.statistics.StatisticsVO;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
@@ -35,15 +34,14 @@ import lombok.extern.slf4j.Slf4j;
 import org.mybatis.spring.annotation.MapperScan;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.SearchStrategy;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
+import javax.persistence.Id;
 import java.io.File;
 import java.io.File;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;

+ 202 - 0
src/test/java/com/gz/ConverOldSystemData.java

@@ -0,0 +1,202 @@
+package com.gz;
+
+import cn.hutool.core.io.FileTypeUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
+import com.gz.dto.archive.ArchiveDTO;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Image;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.PdfWriter;
+import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
+import com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.util.IOUtils;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.MalformedURLException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+@Slf4j
+public class ConverOldSystemData {
+
+    private static final Charset CHARSET = Charset.forName("UTF-8");
+
+
+    private static List<JSON> rows = new ArrayList<>();
+
+    public static void main(String[] args) throws FileNotFoundException {
+        final String archiveTypePath = "H:\\10_建设用地类";
+        // 数据目录文件夹
+        File archiveTypeFolder = FileUtil.file(archiveTypePath);
+        if (archiveTypeFolder == null || !archiveTypeFolder.exists()) {
+            throw new FileNotFoundException("档案分类文件夹不存在");
+        }
+        // 循环档案文件夹
+        for (File archiveFolder : archiveTypeFolder.listFiles()) {
+            if (archiveFolder.isDirectory()) {
+                // 存储图片文件
+                List<File> images = new ArrayList<>();
+                File[] files = archiveFolder.listFiles();
+                // 数据Json
+                JSON archiveJson = null;
+                // 卷内目录Json
+                JSON innerArchiveJson = null;
+                for (File file : files) {
+                    String fileType = FileTypeUtil.getType(file);
+                    if ("jpg".equals(fileType)) {
+                        // 图片文件
+                        images.add(file);
+                    } else if ("json".equals(fileType)) {
+                        // Json文件
+                        String fileName = FileUtil.getName(file);
+                        if (fileName.equals("data.json")) {
+                            archiveJson = JSONUtil.readJSON(file, CHARSET);
+                        } else if (fileName.equals("inner.json")) {
+                            innerArchiveJson = JSONUtil.readJSON(file, CHARSET);
+                        }
+
+                    }
+                }
+                // 排序图片
+                Collections.sort(images, Comparator.comparingInt(o -> Integer.parseInt(getQuantity(FileUtil.getName(o)))));
+                ArchiveDTO archiveDTO = convertArchiveData(archiveJson);
+                imgToPdf(images, StrUtil.format("F:/temp/{}.pdf", archiveDTO.getDh()));
+                log.info("读取档案文件成功 数据:{} 卷内目录:{} 图片文件:{}张", archiveJson, innerArchiveJson, images.size());
+//                break;
+            } else {
+                log.warn("档案分类文件夹下出现非目录文件夹,地址:{}", archiveFolder.getAbsolutePath());
+            }
+        }
+//        ExcelWriter writer = ExcelUtil.getWriter();
+////        writer.addHeaderAlias("bgqx", "保管期限");
+////        writer.addHeaderAlias("dh", "档号");
+////        writer.addHeaderAlias("zny", "止年月");
+////        writer.addHeaderAlias("js", "件数");
+////        writer.addHeaderAlias("bz", "备注");
+////        writer.addHeaderAlias("ys", "页数");
+////        writer.addHeaderAlias("mj", "密级");
+////        writer.addHeaderAlias("ajh", "案卷号");
+////        writer.addHeaderAlias("qny", "起年月");
+////        writer.addHeaderAlias("flh", "分类号");
+////        writer.addHeaderAlias("mlh", "目录号");
+////        writer.addHeaderAlias("nd", "年度");
+////        writer.addHeaderAlias("tm", "题名");
+//
+//        writer.write(rows, true);
+//        FileOutputStream out = new FileOutputStream("F:\\temp\\10_建设用地类.xls");
+//        writer.flush(out, true);
+//        writer.close();
+//        IoUtil.close(out);
+    }
+
+    private static ArchiveDTO convertArchiveData(JSON json) {
+        ArchiveDTO c = new ArchiveDTO();
+        JSONArray a = (JSONArray) json;
+        JSONObject b = (JSONObject) a.get(0);
+//        c.setBgqx(b.getStr("bgqx"));
+        c.setDh(b.getStr("dh"));
+        rows.add(b);
+        return c;
+    }
+
+    /**
+     * 图片转Pdf
+     *
+     * @param images  图片集合
+     * @param pdfPath pdf存储路径
+     * @author LiuChangLan
+     * @since 2022/1/25 14:07
+     */
+    private static void imgToPdf(List<File> images, String pdfPath) throws FileNotFoundException {
+        Document document = new Document();
+        // 设置文档页边距
+        document.setMargins(0, 0, 0, 0);
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(pdfPath);
+            PdfWriter.getInstance(document, fos);
+            // 打开文档
+            document.open();
+            float firstImageHeight = 0;
+            float firstImageWidth = 0;
+            for (int i = 0; i < images.size(); i++) {
+                File image = images.get(i);
+                if ("jpg".equals(FileTypeUtil.getType(image))) {
+                    Image instance = Image.getInstance(image.getAbsolutePath());
+                    // 图片宽度
+                    float imgWidth = instance.getWidth();
+                    // 图片高度
+                    float imgHeight = instance.getHeight();
+                    // 读取第一张图片高度
+                    if (i == 0) {
+                        firstImageWidth = imgWidth;
+                        firstImageHeight = imgHeight;
+                    }
+                    if (imgWidth != firstImageWidth) {
+                        instance.scaleAbsolute(firstImageWidth, firstImageHeight);
+                    }
+                    // 设置页面宽高与图片一致
+                    Rectangle rectangle = new Rectangle(firstImageWidth, firstImageHeight);
+                    document.setPageSize(rectangle);
+                    // 图片居中
+                    instance.setAlignment(Image.ALIGN_CENTER);
+                    // 新建一页添加图片
+                    document.newPage();
+                    document.add(instance);
+                }
+            }
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            document.close();
+            IoUtil.close(fos);
+            log.info("图片转换pdf成功");
+        }
+    }
+
+    /**
+     * 读取字符串中开头数字
+     *
+     * @author LiuChangLan
+     * @since 2022/1/25 14:08
+     */
+    public static String getQuantity(String regular) {
+        int index = 0;
+        for (int i = 0; i < regular.length(); i++) {
+            char c = regular.charAt(i);
+            if (Character.isDigit(c)) {
+                if (i == regular.length() - 1) {
+                    index = i + 1;
+                } else {
+                    index = i;
+                }
+                continue;
+            } else {
+                index = i;
+                break;
+            }
+        }
+        return regular.substring(0, index);
+    }
+}

+ 23 - 0
src/test/java/com/gz/DeleteRedisKey.java

@@ -0,0 +1,23 @@
+package com.gz;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+import javax.annotation.Resource;
+import java.util.Set;
+
+@SpringBootTest
+public class DeleteRedisKey {
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Test
+    public void test(){
+        Set<String> keys = stringRedisTemplate.keys("MOUNT_ERROR*");
+        for (String key : keys) {
+            System.out.println(key);
+        }
+    }
+}