diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240418.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240418.docx new file mode 100644 index 00000000..0e3af6e6 Binary files /dev/null and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240418.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240507.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240507.docx new file mode 100644 index 00000000..08915924 Binary files /dev/null and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/~$市人口变化及其对教育的影响20240507.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/大理州人口变化及其对教育的影响20240424.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/大理州人口变化及其对教育的影响20240424.docx index bd242e66..d8c62fd5 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/大理州人口变化及其对教育的影响20240424.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/大理州人口变化及其对教育的影响20240424.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/德宏傣族景颇族自治州人口变化及其对教育的影响20240416.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/德宏傣族景颇族自治州人口变化及其对教育的影响20240416.docx index 7a5a8ada..1750ff5c 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/德宏傣族景颇族自治州人口变化及其对教育的影响20240416.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/德宏傣族景颇族自治州人口变化及其对教育的影响20240416.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/昆明市人口变化及其对教育的影响20240419.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/昆明市人口变化及其对教育的影响20240419.docx index f00deed5..d9e9fbd5 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/昆明市人口变化及其对教育的影响20240419.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/昆明市人口变化及其对教育的影响20240419.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/曲靖市人口变化及其对教育的影响20240507.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/曲靖市人口变化及其对教育的影响20240507.docx index 3ca20e19..f0390059 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/曲靖市人口变化及其对教育的影响20240507.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/曲靖市人口变化及其对教育的影响20240507.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/楚雄彝族自治州人口变化及其对教育的影响20240507.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/楚雄彝族自治州人口变化及其对教育的影响20240507.docx index 8e1838b3..5f6d15a7 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/楚雄彝族自治州人口变化及其对教育的影响20240507.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/楚雄彝族自治州人口变化及其对教育的影响20240507.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/玉溪市人口变化及其对教育的影响20240416.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/玉溪市人口变化及其对教育的影响20240416.docx index b27857df..6ecb3ee9 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/玉溪市人口变化及其对教育的影响20240416.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/玉溪市人口变化及其对教育的影响20240416.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/红河哈尼族彝族自治州人口变化及其对教育的影响20240419.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/红河哈尼族彝族自治州人口变化及其对教育的影响20240419.docx index 1a62fc16..0109f481 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/红河哈尼族彝族自治州人口变化及其对教育的影响20240419.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/红河哈尼族彝族自治州人口变化及其对教育的影响20240419.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/西双版纳州人口变化及其对教育的影响20240420.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/西双版纳州人口变化及其对教育的影响20240420.docx index 63c76ceb..49f2bbe3 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/西双版纳州人口变化及其对教育的影响20240420.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/西双版纳州人口变化及其对教育的影响20240420.docx differ diff --git a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/迪庆藏族自治州人口变化及其对教育的影响20240424.docx b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/迪庆藏族自治州人口变化及其对教育的影响20240424.docx index cabe415b..bddd2aa0 100644 Binary files a/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/迪庆藏族自治州人口变化及其对教育的影响20240424.docx and b/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/迪庆藏族自治州人口变化及其对教育的影响20240424.docx differ diff --git a/ExtendJar/引用外置jar包.md b/ExtendJar/引用外置jar包.md index b151984a..2e2c16d9 100644 --- a/ExtendJar/引用外置jar包.md +++ b/ExtendJar/引用外置jar包.md @@ -1,6 +1,6 @@ ```shell 将第三方包打进本地仓库,然后依赖本地仓库 - mvn install:install-file -Dfile=D:/dsWork/dsProject/dsBase/ExtendJar/aspose-words-20.12-jdk17-crack.jar -DgroupId=com.aspose -DartifactId=aspose-words -Dversion=20.12 -Dpackaging=jar + mvn install:install-file -Dfile=D:/dsWork/dsProject/dsBase/ExtendJar/aspose-words-21.6.0-jdk17.jar -DgroupId=com.aspose -DartifactId=aspose-words -Dversion=21.6.0 -Dpackaging=jar mvn install:install-file -Dfile=D:/dsWork/dsProject/dsBase/ExtendJar/aspose-cells-23.4.jar -DgroupId=com.aspose -DartifactId=aspose-cells -Dversion=23.4 -Dpackaging=jar mvn install:install-file -Dfile=D:/dsWork/dsProject/dsBase/ExtendJar/aspose.slides-19.3.jar -DgroupId=com.aspose -DartifactId=aspose-slides -Dversion=19.3 -Dpackaging=jar mvn install:install-file -Dfile=D:/dsWork/dsProject/dsBase/ExtendJar/aspose-pdf-22.7.1.cracked.jar -DgroupId=com.aspose -DartifactId=aspose-pdf -Dversion=22.7.1 -Dpackaging=jar diff --git a/Py/Test/DocxTuBiaoRead.py b/Py/Test/DocxTuBiaoRead.py index e7359dab..3bc7446f 100644 --- a/Py/Test/DocxTuBiaoRead.py +++ b/Py/Test/DocxTuBiaoRead.py @@ -7,6 +7,7 @@ docApp = win32com.client.Dispatch('Word.Application') # 是不是打Word显示 docApp.Visible = False docApp.DisplayAlerts = 0 +<<<<<<< HEAD doc = docApp.Documents.Open("c:/b.docx") # @@ -19,6 +20,46 @@ for inline_shape in doc.InlineShapes: sheet = shape.Chart.ChartData.Workbook.Worksheets("Sheet1") # 下一个图表的索引号 idx = idx + 1 +======= +working_dir = r"D:/dsWork/YunNanDsBase/Doc/全省及州市县区人口与教育报告集20241023/16个州市报告2022/分析报告20240510/" + +# doc = docApp.Documents.Open('c:/1.docx') +# doc = docApp.Documents.Open('c:/昭通市人口变化及其对教育的影响20240416.docx') +# doc = docApp.Documents.Open('c:/昆明市人口变化及其对教育的影响20240419.docx') +doc = docApp.Documents.Open(working_dir+'红河哈尼族彝族自治州人口变化及其对教育的影响20240419.docx') + + +# 遍历文档中所有的文字段落,判断是不是以 图+数字开头 +idx = 1 +for para in doc.Paragraphs: + x = para.Range.Text.strip().replace("图 ", "图").replace(" ", " ") + if x.startswith("图"): + print(x) + idx = idx + 1 + +# 遍历文档中的所有内嵌形状 +idx = 1 +for inline_shape in doc.InlineShapes: + if inline_shape.Type == win32com.client.constants.wdInlineShapeChart: # 检查是否为内嵌图表 + shape = doc.InlineShapes(idx) + # 获取图表的标题,此项目中图表没有标题 + # print(shape.Chart.ChartTitle.Text) + sheet = shape.Chart.ChartData.Workbook.Worksheets("Sheet1") + # 行数 + row_size = sheet.UsedRange.rows.Count + # 列数 + col_size = sheet.UsedRange.columns.Count + # 遍历获取表格中的数据 + for i in range(1, row_size + 1): + for j in range(1, col_size + 1): + print(sheet.Cells(i, j).Value, end=" ") + print("") + print("") + # 下一个图表的索引号 + idx = idx + 1 +print(idx-1) + +>>>>>>> cfa48d4d9b83ad3f82bc55fd60f8926d113dfe09 # 关闭文档和Word应用 doc.Close() diff --git a/Py/Test/RepairTuBiao.py b/Py/Test/RepairTuBiao.py new file mode 100644 index 00000000..cf916486 --- /dev/null +++ b/Py/Test/RepairTuBiao.py @@ -0,0 +1,52 @@ +# pip install pywin32 +# https://blog.csdn.net/weixin_42927998/article/details/115086797 +import os + +import win32com +from win32com.client import Dispatch + +# 工作目录 +workingPath = r'D:\dsWork\YunNanDsBase\Doc\全省及州市县区人口与教育报告集20241023\16个州市报告2022\分析报告20240510' + + +# 修复Word文档 +# 经过反复测试发现,WORD文档中的图表,有些POI是无法正确读取的,本来是Sheet1,结果它不认识,说只有一个Sheet0,此时就无法正确读取数据了。 +# 而我通过python+win32com.client.Dispatch可以读取到,直接保存,就修复了这个BUG,真是太神奇了! +def repairWord(docPath): + docApp = win32com.client.Dispatch('Word.Application') + # 是不是打Word显示 + docApp.Visible = False + docApp.DisplayAlerts = 0 + + doc = docApp.Documents.Open(docPath) + # + # # 遍历文档中的所有内嵌形状 + idx = 1 + for inline_shape in doc.InlineShapes: + if inline_shape.Type == win32com.client.constants.wdInlineShapeChart: # 检查是否为内嵌图表 + shape = doc.InlineShapes(idx) + sheet = shape.Chart.ChartData.Workbook.Worksheets("Sheet1") + print(sheet.Name) + # 下一个图表的索引号 + idx = idx + 1 + + # 关闭文档和Word应用 + doc.Close() + docApp.Quit() + + +if __name__ == '__main__': + # 1、修复两层扩展名.docx + for file in os.listdir(workingPath): + if file.endswith('.docx.docx'): + # 完整的路径名称 + docPath = os.path.join(workingPath, file) + print("文件名有误,已修复:" + docPath) + os.rename(docPath, docPath.replace('.docx.docx', '.docx')) + + # 2、修复图表异常问题 + for file in os.listdir(workingPath): + if file.endswith('.docx'): + # 开始修复文档 + repairWord(docPath) + print("修复完成") diff --git a/Py/TuBiao.py b/Py/TuBiao.py new file mode 100644 index 00000000..25be8f1f --- /dev/null +++ b/Py/TuBiao.py @@ -0,0 +1,63 @@ +# pip install pywin32 +# https://blog.csdn.net/weixin_42927998/article/details/115086797 + +import win32com +from openpyxl import Workbook +from win32com.client import constants + +if __name__ == '__main__': + # 文件路径 + taskPath = r'c:/task.txt' + # 读取文件,第一行是docx路径,第二行是第几个图表 + with open(taskPath, 'r', encoding='utf-8') as f: + docPath = f.readline().strip() + tuBiaoNum = int(f.readline().strip()) + + docApp = win32com.client.Dispatch('Word.Application') + # 是否显示Word文档 + docApp.Visible = True + docApp.DisplayAlerts = 0 + + doc = docApp.Documents.Open(docPath) + # 初始化数据列表 + data = [] + + # 遍历文档中的所有内嵌形状 + idx = 1 + for inline_shape in doc.InlineShapes: + if inline_shape.Type == constants.wdInlineShapeChart: # 检查是否为内嵌图表 + + if idx == tuBiaoNum: + shape = doc.InlineShapes(idx) + sheet = shape.Chart.ChartData.Workbook.Worksheets("Sheet1") + # 行数 + row_size = sheet.UsedRange.Rows.Count + # 列数 + col_size = sheet.UsedRange.Columns.Count + + # 读取数据 + for i in range(1, row_size + 1): + row_data = [] + for j in range(1, col_size + 1): + row_data.append(sheet.Cells(i, j).Value) + data.append(row_data) + break + # 下一个图表的索引号 + idx = idx + 1 + + # 关闭文档和Word应用 + doc.Close() + docApp.Quit() + + # 创建一个新的工作簿 + wb = Workbook() + + # 选择默认的工作表 + ws = wb.active + + # 将数据写入工作表 + for row in data: + ws.append(row) + + # 保存工作簿到文件 + wb.save("C:/task.xlsx") diff --git a/pom.xml b/pom.xml index f836df88..011aa19a 100644 --- a/pom.xml +++ b/pom.xml @@ -33,12 +33,9 @@ 5.1.0 - 20.12 23.4 19.3 22.7.1 - - 5.2.5 2.3 @@ -59,7 +56,6 @@ jfinal-undertow ${jfinal-undertow.version} - com.jfinal cos @@ -257,13 +253,20 @@ org.apache.poi poi - ${poi.version} + 5.2.5 org.apache.poi poi-ooxml - ${poi.version} + 5.2.5 + + + + com.alibaba + druid + 1.2.23 + org.yaml @@ -278,17 +281,6 @@ jjwt 0.7.0 - - - org.apache.poi - poi - 5.2.3 - - - org.apache.poi - poi-ooxml - 5.2.3 - com.zendesk diff --git a/src/main/java/com/dsideal/base/Tools/FillData/City/C9.java b/src/main/java/com/dsideal/base/Tools/FillData/City/C9.java index e8399da4..aff274bd 100644 --- a/src/main/java/com/dsideal/base/Tools/FillData/City/C9.java +++ b/src/main/java/com/dsideal/base/Tools/FillData/City/C9.java @@ -4,19 +4,15 @@ import cn.hutool.core.io.FileUtil; import com.dsideal.base.Tools.FillData.ExcelKit.ExcelKit; import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil; import com.dsideal.base.Tools.Util.ReadDocxUtil; +import com.jfinal.kit.StrKit; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xwpf.usermodel.XWPFChart; -import org.apache.poi.xwpf.usermodel.XWPFDocument; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -28,7 +24,8 @@ public class C9 { //示例Excel static String sampleExcelPath = "D:\\dsWork\\YunNanDsBase\\Doc\\待处理\\市\\【9】总人口变化及预测-双\\总人口变化及预测-双.xlsx"; - public static void main(String[] args) throws IOException, InvalidFormatException { + + public static void main(String[] args) throws IOException, InvalidFormatException, InterruptedException { //初始化数据库连接 LocalMysqlConnectUtil.Init(); //实例化 @@ -45,13 +42,14 @@ public class C9 { //样式 XSSFCellStyle headerStyle = ExcelKit.getHeaderStyle(outWorkbook); XSSFCellStyle dataStyle = ExcelKit.getDataStyle(outWorkbook); - //拷贝文件头 ExcelKit.CopyHead(sampleExcelPath, outSheet, headerStyle); - //找到parentPath下一级目录中所有文件 + //递归获取指定目录下所有文件 List files = FileUtil.loopFiles(parentPath, file -> true); int rowIndex = 0; + //----------------------------------------------------------- + //处理这个目录 if (files != null) { for (File file : files) { @@ -63,37 +61,36 @@ public class C9 { //判断是否为docx文件 if (fileName.endsWith(".docx") && !fileName.startsWith("~")) { + if (StrKit.isBlank(cityName)) { + System.out.println("文件名无法解析为城市:" + fileName); + System.exit(0); + } System.out.println("正在处理" + cityName + "市州文件..."); - //读取文件 - String inputUrl = file.getAbsolutePath(); - InputStream is = new FileInputStream(inputUrl); - ZipSecureFile.setMinInflateRatio(-1.0d); - XWPFDocument doc = new XWPFDocument(is); - //排序后的图表 - List charts = ExcelKit.getSortListForXWPFChart(doc.getCharts()); - //数据在图表1 - int firstChartNumber = 1; + int chartNumber = 1; + //chartNumber:第几个图表 + //skipRowCount:跳过的行数,2017年开始,第一行是表头,第二行开始是2022,所以填写了跳过6行 + //expectLimit:期望的数据行数,首先用POI进行解析,如果获取的行数大于预期行数,就是正确的,否则就需要二次调用python进行读取 + List> source = ExcelKit.getChartData(file.getAbsolutePath(), chartNumber, 6, 20); - if (cityName.contains("昭通")) { - for (int i = 0; i < charts.size(); i++) { - XSSFWorkbook workbook = charts.get(i).getWorkbook(); - List> source1 = ExcelKit.readSheet(workbook, 1); - System.out.println(source1); - } + //遍历source + for (List r : source) { + Row outRow = outSheet.createRow(++rowIndex); + // 导出数据 + //上级行政区划,行政区划,年份,总人口变化,总人口预测 + int year = Integer.parseInt(r.getFirst().substring(0, 4)); + double value = Double.parseDouble(r.get(1)); + if (year < 2023) { + ExcelKit.putData(outRow, new ArrayList<>(Arrays.asList(cityName, "云南省", r.getFirst().substring(0, 4), String.format("%.2f", value), "")), dataStyle); + } + if (year > 2023) { + ExcelKit.putData(outRow, new ArrayList<>(Arrays.asList(cityName, "云南省", r.getFirst().substring(0, 4), "", String.format("%.2f", value))), dataStyle); + } + if (year == 2023) { + ExcelKit.putData(outRow, new ArrayList<>(Arrays.asList(cityName, "云南省", r.getFirst().substring(0, 4), String.format("%.2f", value), String.format("%.2f", value))), dataStyle); + } } - //XSSFWorkbook workbook = charts.get(firstChartNumber - 1).getWorkbook(); - //List> source1 = ExcelKit.readSheet(workbook,1); - -// System.out.println(source1); -// //遍历source1 -// for (List r : source1) { -// //Row outRow = outSheet.createRow(++rowIndex); -// // 导出数据 -// //年份,总量分类,区域分类,总量数值,区域数值,行政区划,上级行政区划 -// //ExcelKit.putData(outRow, new ArrayList<>(Arrays.asList(r.getFirst(), "总入园数", "", r.get(4), "", cityName, "云南省")), dataStyle); -// } } } } diff --git a/src/main/java/com/dsideal/base/Tools/FillData/ExcelKit/ExcelKit.java b/src/main/java/com/dsideal/base/Tools/FillData/ExcelKit/ExcelKit.java index 19a0a3ec..94fac8d4 100644 --- a/src/main/java/com/dsideal/base/Tools/FillData/ExcelKit/ExcelKit.java +++ b/src/main/java/com/dsideal/base/Tools/FillData/ExcelKit/ExcelKit.java @@ -2,19 +2,31 @@ package com.dsideal.base.Tools.FillData.ExcelKit; import com.dsideal.base.DataEase.Model.ExcelReader; import com.jfinal.kit.StrKit; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.usermodel.XWPFChart; +import org.apache.poi.xwpf.usermodel.XWPFDocument; import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class ExcelKit { + //与python交互使用的excel文件路径 + public static String excelPath = "c:/task.xlsx"; + //执行的python路径,这里我使用的是anaconda3的python,路径自行修改,注意要在这个环境中pip安装了python-docx,否则会报错 + public static String python = "D:\\anaconda3\\envs\\py310\\python.exe"; + //python脚本路径 + public static String py = "D:\\dsWork\\YunNanDsBase\\Py\\TuBiao.py"; + /** * 将xls转换为xlsx * @@ -23,7 +35,7 @@ public class ExcelKit { */ public static String ConvertXlsToXlsx(String sourceExcel) throws IOException { if (sourceExcel.endsWith(".xls")) { - ExcelUtil.xlsChangeXlsx(sourceExcel, sourceExcel + "x"); + ExcelCoreUtil.xlsChangeXlsx(sourceExcel, sourceExcel + "x"); //删除旧的文件 ExcelKit.delExcel(sourceExcel); sourceExcel = sourceExcel + "x"; @@ -135,12 +147,13 @@ public class ExcelKit { } public static List> readSheet(XSSFWorkbook workbook, int skipRowCount) throws IOException { - XSSFSheet sheet = workbook.getSheet("Sheet1"); + XSSFSheet sheet = workbook.getSheetAt(0); List> array = new ArrayList<>(); //遍历输出sheet的内容 int rowIndex = 0; // 遍历工作表中的所有行 if (sheet == null) return array; + for (Row row : sheet) { rowIndex++; if (rowIndex <= skipRowCount) continue;//跳过指定的行数 @@ -330,4 +343,149 @@ public class ExcelKit { } return --rlt; } + + /** + * 调用python+com读取WORD中的图表 + * + * @throws IOException + * @throws InterruptedException + */ + public static void callPythonRead() throws IOException, InterruptedException { + delExcel(excelPath); + // 创建ProcessBuilder对象,并设置Python脚本的路径 + ProcessBuilder processBuilder = new ProcessBuilder(python, py); + // 重定向错误流到标准输出,这样可以在Java中捕获所有的输出 + processBuilder.redirectErrorStream(true); + // 启动进程 + Process process = processBuilder.start(); + // 读取Python脚本的输出 + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + // 等待Python脚本执行完成 + process.waitFor(); + } + + public static void callPythonPrepare(String docPath, int tuBiaoNum) throws IOException { + String taskTxt = "c:/task.txt"; + //如果文件存在则删除 + if (new File(taskTxt).exists()) { + new File(taskTxt).delete(); + } + //将docPath写入taskTxt,第一行 + //将tuBiaoNum写入taskTxt,第二行 + FileWriter writer = new FileWriter(taskTxt, StandardCharsets.UTF_8); + writer.write(docPath); + writer.write("\n"); + writer.write(String.valueOf(tuBiaoNum)); + writer.write("\n"); + writer.flush(); + writer.close(); + } + + /** + * 读取excel文件 + * @param excelFilePath + * @param skipRows + * @return + */ + public static List> readExcelToList(String excelFilePath, int skipRows) { + List> data = new ArrayList<>(); + try (FileInputStream inputStream = new FileInputStream(excelFilePath)) { + Workbook workbook = new XSSFWorkbook(inputStream); + Sheet sheet = workbook.getSheetAt(0); // 获取第一个Sheet + + // 创建一个迭代器来遍历行,跳过指定数量的行 + Iterator rowIterator = sheet.iterator(); + while (skipRows > 0 && rowIterator.hasNext()) { + rowIterator.next(); + skipRows--; + } + + // 遍历每一行 + while (rowIterator.hasNext()) { + Row row = rowIterator.next(); + List rowData = new ArrayList<>(); + // 遍历每一行中的每一列 + Iterator cellIterator = row.cellIterator(); + + while (cellIterator.hasNext()) { + Cell cell = cellIterator.next(); + // 根据单元格的不同类型获取数据 + switch (cell.getCellType()) { + case STRING: + rowData.add(cell.getStringCellValue()); + break; + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + rowData.add(cell.getDateCellValue().toString()); + } else { + rowData.add(Double.toString(cell.getNumericCellValue())); + } + break; + case BOOLEAN: + rowData.add(Boolean.toString(cell.getBooleanCellValue())); + break; + case FORMULA: + rowData.add(cell.getCellFormula()); + break; + default: + rowData.add(""); + break; + } + } + data.add(rowData); + } + workbook.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return data; + } + + /** + * 获取指定文档中指定图表数据 + * + * @param docPath 文档路径 + * @param chartNumber 图表序号 + * @param skipRowCount 跳过的行数 + * @return 结果数据 + * @throws IOException + * @throws InvalidFormatException + */ + public static List> getChartData(String docPath, int chartNumber, int skipRowCount, int expectLimit) throws IOException, InvalidFormatException, InterruptedException { + InputStream is = new FileInputStream(docPath); + ZipSecureFile.setMinInflateRatio(-1.0d); + XWPFDocument doc = new XWPFDocument(is); + //排序后的图表 + List charts = ExcelKit.getSortListForXWPFChart(doc.getCharts()); + XSSFWorkbook workbook = charts.get(chartNumber).getWorkbook(); + List> data = ExcelKit.readSheet(workbook, skipRowCount); + is.close(); + + //如果达到目标预期的数量,就直接返回poi获取的数据列表 + int totalRow = data.size() + skipRowCount; + if (totalRow < expectLimit) { + System.out.println("期望数量>=" + expectLimit + ",现在只有" + totalRow + "条,理解为POI读取WORD图表存在问题,使用Python进行二次获取数据..."); + // 留出足够的com关闭word的时间长度,否则会有异常 + Thread.sleep(3000); + //否则调用python+com进行再次获取数据列表,这次获取的可能才是对的 + //写入交互文本文件 + ExcelKit.callPythonPrepare(docPath, chartNumber); + //对图表进行读取 + ExcelKit.callPythonRead(); + //读取生成的EXCEL,使用POI就可以了 + //使用POI + int skipRows = 1; // 假设我们要跳过第一行 + data = ExcelKit.readExcelToList(ExcelKit.excelPath, skipRows); + System.out.println("二次获取数据条目数量:" + data.size() + ",期望数量=" + expectLimit); + + }else{ + System.out.println("期望数量>=" + expectLimit + ",现在有" + totalRow + "条,理解为数据读取正确,直接返回POI获取的数据列表..."); + } + System.out.println("=========================================================================================================="); + return data; + } } diff --git a/src/main/java/com/dsideal/base/Tools/FillData/Test/TestBadExcel.java b/src/main/java/com/dsideal/base/Tools/FillData/Test/TestBadExcel.java new file mode 100644 index 00000000..dbaf102b --- /dev/null +++ b/src/main/java/com/dsideal/base/Tools/FillData/Test/TestBadExcel.java @@ -0,0 +1,71 @@ +package com.dsideal.base.Tools.FillData.Test; + +import cn.hutool.core.io.FileUtil; +import com.dsideal.base.Tools.FillData.ExcelKit.ExcelKit; +import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil; +import com.dsideal.base.Tools.Util.ReadDocxUtil; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.util.ZipSecureFile; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xwpf.usermodel.XWPFChart; +import org.apache.poi.xwpf.usermodel.XWPFDocument; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TestBadExcel { + //开始读取市州word文档 + static String parentPath = "D:\\dsWork\\YunNanDsBase\\Doc\\全省及州市县区人口与教育报告集20241023\\16个州市报告2022\\分析报告20240510"; + + //示例Excel + static String sampleExcelPath = "D:\\dsWork\\YunNanDsBase\\Doc\\待处理\\市\\【11】教育资源配置发展预测\\教育资源配置发展预测(人).xlsx"; + + public static void main(String[] args) throws IOException, InvalidFormatException { + //初始化数据库连接 + LocalMysqlConnectUtil.Init(); + //实例化 + ReadDocxUtil ru = new ReadDocxUtil(); + + + //找到parentPath下一级目录中所有文件 + List files = FileUtil.loopFiles(parentPath, file -> true); + int rowIndex = 0; + //处理这个目录 + if (files != null) { + for (File file : files) { + //判断file是不是目录,是目录的需要跳过 + if (file.isDirectory()) continue; + //城市名称 + String cityName = ru.getCityOrAreaName(file.getName()); + String fileName = file.getName(); + + //判断是否为docx文件 + if (fileName.endsWith(".docx") && !fileName.startsWith("~")) { + System.out.println("正在处理" + cityName + "市州文件..."); + //读取文件 + String inputUrl = file.getAbsolutePath(); + InputStream is = new FileInputStream(inputUrl); + ZipSecureFile.setMinInflateRatio(-1.0d); + XWPFDocument doc = new XWPFDocument(is); + //排序后的图表 + List charts = ExcelKit.getSortListForXWPFChart(doc.getCharts()); + + //数据在图表36,教职工总量 + int firstChartNumber = 36; + if(cityName.contains("西双版纳州")){ + System.out.println("he"); + } + charts.get(firstChartNumber - 1).getWorkbook(); + } + } + } + } +} diff --git a/src/main/java/com/dsideal/base/Tools/FillData/Test/TestCallPython.java b/src/main/java/com/dsideal/base/Tools/FillData/Test/TestCallPython.java new file mode 100644 index 00000000..f64e259b --- /dev/null +++ b/src/main/java/com/dsideal/base/Tools/FillData/Test/TestCallPython.java @@ -0,0 +1,29 @@ +package com.dsideal.base.Tools.FillData.Test; + +import com.dsideal.base.Tools.FillData.ExcelKit.ExcelKit; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class TestCallPython { + + + public static void main(String[] args) throws InterruptedException, IOException { + //哪个word文档 + String docPath = "D:\\dsWork\\YunNanDsBase\\Doc\\全省及州市县区人口与教育报告集20241023\\16个州市报告2022\\分析报告20240510\\丽江市人口变化及其对教育的影响20240418.docx"; + //第几个图表 + int tuBiaoNum = 1; + //Excel文件生成位置 + String excelPath = "c:/task.xlsx"; + + //写入交互文本文件 + ExcelKit.callPythonPrepare(docPath, tuBiaoNum); + //对图表进行读取 + ExcelKit.delExcel(excelPath); + ExcelKit.callPythonRead(); + //读取生成的EXCEL,使用POI就可以了 + List> sheetList = ExcelKit.readSheet(excelPath, 1); + System.out.println(sheetList); + } +} diff --git a/src/main/java/com/dsideal/base/Tools/Util/LocalMysqlConnectUtil.java b/src/main/java/com/dsideal/base/Tools/Util/LocalMysqlConnectUtil.java index f85d3671..00c08771 100644 --- a/src/main/java/com/dsideal/base/Tools/Util/LocalMysqlConnectUtil.java +++ b/src/main/java/com/dsideal/base/Tools/Util/LocalMysqlConnectUtil.java @@ -6,6 +6,7 @@ import com.dsideal.base.Tools.Step1_DataSetInit; import com.jfinal.kit.Prop; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.activerecord.dialect.MysqlDialect; +import com.jfinal.plugin.druid.DruidPlugin; import com.jfinal.plugin.hikaricp.HikariCpPlugin; import java.io.File; @@ -18,9 +19,9 @@ public class LocalMysqlConnectUtil { String configFile = "application.yaml"; PropKit = new YamlProp(configFile); - HikariCpPlugin masterPlugin = new HikariCpPlugin(PropKit.get("mysql.jdbcUrl"), PropKit.get("mysql.user"), + DruidPlugin masterPlugin = new DruidPlugin(PropKit.get("mysql.jdbcUrl"), PropKit.get("mysql.user"), PropKit.get("mysql.password").trim(), PropKit.get("mysql.driverClassName")); - HikariCpPlugin dataEasePlugin = new HikariCpPlugin(PropKit.get("mysql.jdbcUrl").replace("ds_db", DataEaseModel.DB_NAME), PropKit.get("mysql.user"), + DruidPlugin dataEasePlugin = new DruidPlugin(PropKit.get("mysql.jdbcUrl").replace("ds_db", DataEaseModel.DB_NAME), PropKit.get("mysql.user"), PropKit.get("mysql.password").trim(), PropKit.get("mysql.driverClassName")); masterPlugin.start();