From 57df00641a016c348bf4f28c8e6cea99f178bec1 Mon Sep 17 00:00:00 2001 From: Mzaxd Date: Tue, 30 May 2023 14:10:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=B0=86=E5=88=B7=E6=96=B0=E5=85=A8?= =?UTF-8?q?=E6=96=87=E6=A3=80=E7=B4=A2=E6=95=B0=E6=8D=AE=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=A0=B9=E6=8D=AEFileId=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/adc/da/DataDictionaryGenerator.java | 164 ++++++++++++++++++ .../adc/da/report/eo/ReportContentEntity.java | 6 + .../impl/IReportContentServiceImpl.java | 17 +- .../service/impl/IReportServiceImpl.java | 50 +++++- .../adc/da/report/util/FileContentUtil.java | 3 +- 5 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 adc-da-main/src/test/java/com/adc/da/DataDictionaryGenerator.java diff --git a/adc-da-main/src/test/java/com/adc/da/DataDictionaryGenerator.java b/adc-da-main/src/test/java/com/adc/da/DataDictionaryGenerator.java new file mode 100644 index 0000000..c7c9d79 --- /dev/null +++ b/adc-da-main/src/test/java/com/adc/da/DataDictionaryGenerator.java @@ -0,0 +1,164 @@ +package com.adc.da; + +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.*; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.poi.xwpf.usermodel.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class DataDictionaryGenerator { + + /** + * 生成数据字典Word + */ + @Test + public void generate() throws Exception { + // Connect to the database + String url = "jdbc:mysql://localhost:3306/report_library?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai"; + String username = "root"; + String password = "rootroot"; + Connection connection = DriverManager.getConnection(url, username, password); + + // Get metadata + DatabaseMetaData metaData = connection.getMetaData(); + // Specify the database name + String databaseName = "report_library"; // Replace "report_library" with the actual database name + + // Get tables in the specified database + ResultSet tables = metaData.getTables(databaseName, null, "%", null); + + // Create a new Word document + XWPFDocument document = new XWPFDocument(); + + int tableCounter = 1; + + // Iterate over the tables + while (tables.next()) { + String tableName = tables.getString(3); + + // Add the table name to the document + XWPFParagraph tableNameParagraph = document.createParagraph(); + XWPFRun run = tableNameParagraph.createRun(); + + // Set table name as "Table 1: 表名" + String tableNumber = tableCounter + ": "; + String tableNameText = tableNumber + tableName; + run.setText(tableNameText); + run.setBold(true); + + // Set font size + run.setFontSize(12); // 12 points for font size (equivalent to three号字号) + + // Increment table counter + tableCounter++; + + // Create table + XWPFTable table = document.createTable(); + CTTblWidth tableWidth = table.getCTTbl().addNewTblPr().addNewTblW(); + tableWidth.setType(STTblWidth.PCT); + tableWidth.setW(BigInteger.valueOf(5000)); // Set the table width (10000 = 100%) + + // create header row + XWPFTableRow headerRow = table.getRow(0); + headerRow.getCell(0).setText("列名"); + headerRow.addNewTableCell().setText("中文含义"); + headerRow.addNewTableCell().setText("数据类型"); + headerRow.addNewTableCell().setText("主键"); + headerRow.addNewTableCell().setText("外键"); + headerRow.addNewTableCell().setText("不为空"); + headerRow.addNewTableCell().setText("备注"); + + // Get columns + ResultSet columns = metaData.getColumns(null, null, tableName, "%"); + + // get primary keys + ResultSet primaryKeys = metaData.getPrimaryKeys(null, null, tableName); + Set primaryKeySet = new HashSet<>(); + while (primaryKeys.next()) { + primaryKeySet.add(primaryKeys.getString("COLUMN_NAME")); + } + + // Pattern for matching remarks + Pattern pattern = Pattern.compile("([^((]+)[((]([^))]+)[))]"); + + // Iterate over the columns + while (columns.next()) { + String columnName = columns.getString(4); + int columnSize = columns.getInt("COLUMN_SIZE"); + String columnType = columns.getString(6) + "(" + columnSize + ")"; + String isNullable = columns.getString(18); + boolean isNotNull = isNullable.equals("NO"); + + // Check if column is primary key + String isPrimaryKey = primaryKeySet.contains(columnName) ? "是" : "否"; + + String isForeignKey = "否"; + + // Extracting Chinese meaning and remarks from the remarks column + String fullRemarks = columns.getString("REMARKS"); + Matcher matcher = pattern.matcher(fullRemarks); + + String chineseMeaning = ""; + String remarks = ""; + if (matcher.find()) { + chineseMeaning = matcher.group(1); + remarks = matcher.group(2); + } else { + chineseMeaning = fullRemarks; + } + + // Add the column details to the table + XWPFTableRow row = table.createRow(); + XWPFRun cellRun = row.getCell(0).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(columnName); + + cellRun = row.getCell(1).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(chineseMeaning); + + cellRun = row.getCell(2).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(columnType); + + cellRun = row.getCell(3).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(isPrimaryKey); + + cellRun = row.getCell(4).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(isForeignKey); + + cellRun = row.getCell(5).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(isNotNull ? "是" : "否"); + + cellRun = row.getCell(6).getParagraphs().get(0).createRun(); + cellRun.setFontSize(10); + cellRun.setText(remarks); + } + // Create an empty paragraph + XWPFParagraph emptyParagraph = document.createParagraph(); + emptyParagraph.setSpacingAfter(200); // Set the spacing after the paragraph (adjust the value as needed) + } + + // Save the document + document.write(Files.newOutputStream(Paths.get("DataDictionary.docx"))); + + // Close the document + document.close(); + } +} \ No newline at end of file diff --git a/adc-da-report/src/main/java/com/adc/da/report/eo/ReportContentEntity.java b/adc-da-report/src/main/java/com/adc/da/report/eo/ReportContentEntity.java index 0fedacb..d34b4d2 100644 --- a/adc-da-report/src/main/java/com/adc/da/report/eo/ReportContentEntity.java +++ b/adc-da-report/src/main/java/com/adc/da/report/eo/ReportContentEntity.java @@ -35,6 +35,12 @@ public class ReportContentEntity implements Serializable { @TableField(value = "report_id") private String reportId; + /** + * 报告id + */ + @TableField(value = "file_ids") + private String fileIds; + /** * 文件内容 */ diff --git a/adc-da-report/src/main/java/com/adc/da/report/service/impl/IReportContentServiceImpl.java b/adc-da-report/src/main/java/com/adc/da/report/service/impl/IReportContentServiceImpl.java index ef2a98b..55d5519 100644 --- a/adc-da-report/src/main/java/com/adc/da/report/service/impl/IReportContentServiceImpl.java +++ b/adc-da-report/src/main/java/com/adc/da/report/service/impl/IReportContentServiceImpl.java @@ -1,5 +1,6 @@ package com.adc.da.report.service.impl; +import cn.hutool.json.JSONUtil; import com.adc.da.report.dao.mysql.FileDao; import com.adc.da.report.dao.mysql.ReportFileDao; import com.adc.da.report.eo.FileEntity; @@ -72,6 +73,7 @@ public class IReportContentServiceImpl extends ServiceImpl reportContentFileIdList = new ArrayList<>(); for (String fileId : fileIds) { //获取文件 FileEntity fileEntity = fileDao.selectById(fileId); @@ -87,16 +89,27 @@ public class IReportContentServiceImpl extends ServiceImpl public ResponseMessage refreshReportContent() { //找出所有能生成内容的报告id LambdaQueryWrapper reportFileLambdaQueryWrapper = new LambdaQueryWrapper<>(); + //只找不在流程中的报告 reportFileLambdaQueryWrapper.ne(ReportFile::getState, 1); List reportFileList = iReportFileService.list(reportFileLambdaQueryWrapper); + //所有报告的id Set allReportIdSet = reportFileList.stream().map(ReportFile::getReportId).collect(Collectors.toSet()); - //找出已经生成过的报告id + //所有文件的id + Set allFileIdSet = reportFileList.stream().map(ReportFile::getFileId).collect(Collectors.toSet()); + List reportContentList = iReportContentService.list(); + //找出已经生成过的报告id Set generatedReportIdSet = reportContentList.stream().map(ReportContentEntity::getReportId).collect(Collectors.toSet()); - //获取缺失的报告id + //找出已经生成过的报告的fileId + List generatedFileIds = reportContentList.stream().map(ReportContentEntity::getFileIds).collect(Collectors.toList()); + Set generatedFileIdSet = new HashSet<>(); + for (String fileIds : generatedFileIds) { + // 将JSONArray转换为List + // 解析JSON字符串为JSONArray + if (StrUtil.isNotBlank(fileIds)) { + JSONArray jsonArray = JSONUtil.parseArray(fileIds); + List fileIdList = jsonArray.toList(String.class); + generatedFileIdSet.addAll(fileIdList); + } + } + + //获取缺失的文件id + allFileIdSet.removeAll(generatedFileIdSet); allReportIdSet.removeAll(generatedReportIdSet); - //需要生成的数量 - int needGenerateCount = allReportIdSet.size(); - log.info("发现缺少" + needGenerateCount + "条报告的内容"); + + //需要生成的文件的数量 + int needGenerateFileCount = allFileIdSet.size(); + int needGenerateReportCount = allReportIdSet.size(); + log.info("发现缺少" + needGenerateFileCount + "个文件的内容"); + log.info("有" + needGenerateReportCount + "个报告需要重新生成"); //实际生成的数量 int count = 0; + List failGenerateReportId = new ArrayList<>(); //生成报告内容 for (String reportId : allReportIdSet) { //修改报表内容表(先删后增) @@ -242,15 +267,19 @@ public class IReportServiceImpl extends ServiceImpl count++; } catch (IOException e) { log.error("获取reportId为{}的报告内容失败", reportId); + failGenerateReportId.add(reportId); log.error(String.valueOf(e)); } } log.info("实际生成" + count + "条报告的内容"); - if (needGenerateCount == count) { + if (needGenerateReportCount == count) { + if (needGenerateReportCount == 0) { + return Result.success("未发现缺失报告内容,无需生成"); + } return Result.success("成功,全部生成完毕,共" + count + "条"); } else { - int missing = needGenerateCount - count; - return Result.success("失败," + missing + "条报告的内容生成失败"); + int missing = needGenerateReportCount - count; + return Result.success("失败," + missing + "条报告的内容生成失败,请检查其是否有空文件或其余问题,失败的报告id为" + failGenerateReportId); } } @@ -449,7 +478,10 @@ public class IReportServiceImpl extends ServiceImpl LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(ReportContentEntity::getReportId, idList); iReportContentService.remove(wrapper); - //TODO 删除文件关联 + //删除文件关联 + LambdaQueryWrapper reportFileLambdaQueryWrapper = new LambdaQueryWrapper<>(); + reportFileLambdaQueryWrapper.in(ReportFile::getReportId, idList); + iReportFileService.remove(reportFileLambdaQueryWrapper); return nameList; } diff --git a/adc-da-report/src/main/java/com/adc/da/report/util/FileContentUtil.java b/adc-da-report/src/main/java/com/adc/da/report/util/FileContentUtil.java index cff0fa3..ab7f22a 100644 --- a/adc-da-report/src/main/java/com/adc/da/report/util/FileContentUtil.java +++ b/adc-da-report/src/main/java/com/adc/da/report/util/FileContentUtil.java @@ -10,6 +10,7 @@ import org.apache.poi.hslf.usermodel.HSLFShape; import org.apache.poi.hslf.usermodel.HSLFSlide; import org.apache.poi.hslf.usermodel.HSLFTextShape; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xslf.usermodel.XMLSlideShow; @@ -87,7 +88,7 @@ public class FileContentUtil { content = new StringBuilder(stripper.getText(document)); default: } - } catch (Exception e) { + } catch (NotOfficeXmlFileException e) { fis.close(); log.info("文件内容抽取失败,原因可能是上传的文件为空文件"); }