From f5cf40596d15ed891f36614f2b8ccb4dfb626984 Mon Sep 17 00:00:00 2001 From: tain198127 Date: Thu, 19 Sep 2024 23:37:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=A4=9A=E4=B8=AApdma.json=E5=88=B0excel?= =?UTF-8?q?=E7=9A=84=E8=83=BD=E5=8A=9B=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E5=AF=B9=E5=BA=94=E7=9A=84=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=B9=B6=E4=B8=94=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E7=8E=87=E8=B6=85=E8=BF=8790%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 28 ++ .../java/cn/com/chiner/java/Application.java | 1 + .../java/command/impl/GenExcelMergedImpl.java | 308 ++++++++++++++++++ .../com/chiner/java/model/ColumnHeader.java | 22 ++ .../java/cn/com/chiner/java/model/Dict.java | 25 ++ .../java/cn/com/chiner/GenXlsxMergeTest.java | 17 + .../command/impl/GenExcelMergedImplTest.java | 165 ++++++++++ 7 files changed, 566 insertions(+) create mode 100644 src/main/java/cn/com/chiner/java/command/impl/GenExcelMergedImpl.java create mode 100644 src/test/java/cn/com/chiner/GenXlsxMergeTest.java create mode 100644 src/test/java/cn/com/chiner/java/command/impl/GenExcelMergedImplTest.java diff --git a/pom.xml b/pom.xml index 38d9313..47c0444 100644 --- a/pom.xml +++ b/pom.xml @@ -233,6 +233,34 @@ antlr4-runtime 4.13.1 + + + + org.mockito + mockito-core + 3.8.0 + test + + + org.powermock + powermock-core + 2.0.9 + + + org.powermock + powermock-module-junit4 + 2.0.9 + test + + + org.powermock + powermock-api-mockito2 + 2.0.9 + test + + + + diff --git a/src/main/java/cn/com/chiner/java/Application.java b/src/main/java/cn/com/chiner/java/Application.java index ffcb743..90485a7 100644 --- a/src/main/java/cn/com/chiner/java/Application.java +++ b/src/main/java/cn/com/chiner/java/Application.java @@ -53,6 +53,7 @@ public class Application { put("DDLParseImpl",DDLParseImpl.class); //通过语法树解析DDL文件 put("GenExcelImpl",GenExcelImpl.class); //生成EXCEL文档 put("GenStandardFieldExcelImpl",GenStandardFieldExcelImpl.class); //生成标准字段库EXCEL文档 + put("GenExcelMergedImpl", GenExcelMergedImpl.class); }}; /** diff --git a/src/main/java/cn/com/chiner/java/command/impl/GenExcelMergedImpl.java b/src/main/java/cn/com/chiner/java/command/impl/GenExcelMergedImpl.java new file mode 100644 index 0000000..7670e2b --- /dev/null +++ b/src/main/java/cn/com/chiner/java/command/impl/GenExcelMergedImpl.java @@ -0,0 +1,308 @@ +package cn.com.chiner.java.command.impl; + +import cn.com.chiner.java.command.Command; +import cn.com.chiner.java.command.ExecResult; +import cn.com.chiner.java.command.impl.excel.ExcelCommonUtils; +import cn.com.chiner.java.command.impl.excel.ExcelDocUtils; +import cn.com.chiner.java.model.*; +import cn.com.chiner.java.model.Module; +import cn.fisok.raw.io.ByteInputStream; +import cn.fisok.raw.kit.FileKit; +import cn.fisok.raw.kit.IOKit; +import cn.fisok.raw.kit.JSONKit; +import org.apache.poi.ss.usermodel.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.*; + +/** + * 归集多个json文件合并成为统一的excel + * 在实际项目中,pdma.json文件可能是多人协作编写,因此可能有多个pdma.json文件 + * 当前系统中只能针对单个pdma.json文件转换为excel,为了方便整合,特此开发该类 + */ +public class GenExcelMergedImpl implements Command { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * + * @param params dataDir json 的目录 + * @param params outFile 输出文档目录 + * @param params out 输出结果的json文件 + * @return + * @throws IOException + */ + @Override + public ExecResult exec(Map params) throws IOException { + String dataDir = params.get("dataDir"); + String outFile = params.get("outFile"); //输出的文档文件 + String type = params.containsKey("type")?params.get("type"):"json"; + String out = params.get("out"); //输出的结果json文件 + ExecResult ret = new ExecResult(); + try{ + if(Objects.equals(type, "json")) + execjson(dataDir, outFile,out); + else if (Objects.equals(type, "sql")){ + //todo 结息sql到pdma.json,并且可以根据批量的sql文件批量的生成json文件 + } + ret.setStatus(ExecResult.SUCCESS); + ret.setBody(outFile); + }catch (Exception e) { + String message = e.getMessage(); + if(message == null){ + message = e.toString(); + } + ret.setStatus(ExecResult.FAILED); + ret.setBody(message); + logger.error("", e); + } + return ret; + } + /** + * + * @param dataDir json文件所在的位置 + * @param outFile 输出excel位置 + * @param out 返回的body + */ + protected void execjson(String dataDir, String outFile, String out) throws IOException { + List pdmajsonFiles = readPdmaJson(dataDir); + logger.debug("读入完毕"); + Set headers =new HashSet<>(); + Module modules = analyze(pdmajsonFiles,headers); + logger.debug("分析完毕"); + List headerList = transSetToList(headers); + fillExcelDataSimple(modules,outFile,headerList); + + } + + + /** + * 填充EXCEL数据,使用简单不分组的模式 + * @param module 单个的模块对象 + */ + private void fillExcelDataSimple(Module module,String outFile,List columnHeaders){ + FileOutputStream fos = null; + InputStream orginIn = getClass().getResourceAsStream("/xlsx/tpl-by-simple.xlsx"); + ByteInputStream byteIn = null; + + try { + fos = new FileOutputStream(outFile); + byteIn = IOKit.convertToByteArrayInputStream(orginIn); + Workbook workbook = ExcelCommonUtils.getWorkbook(byteIn); + + Font defaultFont = workbook.createFont(); + defaultFont.setFontName("宋体-简"); // 设置字体为宋体 + CellStyle defaultCellStyle = workbook.createCellStyle(); + defaultCellStyle.setFont(defaultFont); // 将默认字体应用到样式中 + logger.debug("开始填充字典"); + //填充字典 + Sheet dictSheet = workbook.getSheetAt(1); + int startRow = 2; + List dicts = module.getDicts(); + if(dicts == null){ + return; + } + for (Dict dict : dicts) { + List items = dict.getItems(); + if (items == null) { + continue; + } + boolean isFirst = true; + for (int j=0;j entities = module.getEntities(); + if(entities == null || entities.isEmpty()){ + return; + } + for(int i=0;i readPdmaJson(String dataDir) throws IOException { + List pdmJsonList = new ArrayList<>(); + logger.debug("dataDir:{}",dataDir); + Files.walkFileTree(Paths.get(dataDir), new SimpleFileVisitor(){ + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if(file.toString().endsWith("pdma.json")){ + pdmJsonList.add(file.toFile()); + } + return super.visitFile(file, attrs); + } + }); + + logger.debug("内容是:{}",pdmJsonList); + return pdmJsonList; + } + + /** + * 将json文件转换为module + * @param files + * @return + */ + protected Module analyze(List files,Set columnHeaders){ + Project project = new Project(); + Set entities = new HashSet<>(); + Set views= new HashSet<>(); + Set dicts= new HashSet<>(); + Set diagrams= new HashSet<>(); + + for(File f: files){ + try { + String jsonText = parseFile(f); + project = JSONKit.jsonToBean(jsonText,Project.class); + + ProjectOriginal projectOriginal = JSONKit.jsonToBean(jsonText,ProjectOriginal.class); + Object objectProfile = projectOriginal.getProfile(); + List objectEntities = projectOriginal.getEntities(); + List objectViews = projectOriginal.getViews(); + List objectDicts = projectOriginal.getDicts(); + List objectDiagrams = projectOriginal.getDiagrams(); + String textEntities = JSONKit.toJsonString(objectEntities); + String textViews = JSONKit.toJsonString(objectViews); + String textDicts = JSONKit.toJsonString(objectDicts); + String textDiagrams = JSONKit.toJsonString(objectDiagrams); + String textProfile=JSONKit.toJsonString(objectProfile); + + Profile profile=JSONKit.jsonToBean(textProfile,Profile.class); + + columnHeaders.addAll(Optional.ofNullable(profile.getHeaders()).orElse(new ArrayList<>())); + List tmpentities = Optional.ofNullable(JSONKit.jsonToBeanList(textEntities,TableEntity.class)).orElse(new ArrayList<>()); + List tmpviews = Optional.ofNullable(JSONKit.jsonToBeanList(textViews,View.class)).orElse(new ArrayList<>()); + List tmpdicts = Optional.ofNullable(JSONKit.jsonToBeanList(textDicts,Dict.class)).orElse(new ArrayList<>()); + List tmpdiagrams = Optional.ofNullable(JSONKit.jsonToBeanList(textDiagrams,Diagram.class)).orElse(new ArrayList<>()); + + for(TableEntity entity : tmpentities){ + entity.setDicts(tmpdicts); + entity.fillFieldsCalcValue(); + } + entities.addAll(tmpentities); + views.addAll(tmpviews); + dicts.addAll(tmpdicts); + diagrams.addAll(tmpdiagrams); + } + catch (Exception ex){ + logger.error("parseFile转换json格式报错:{}",ex); + } + } + + Module module = new Module(); + module.setDefKey(project.getName()); + module.setDefName(project.getAvatar()); + module.setDicts(transSetToList(dicts)); + module.setEntities(transSetToList(entities)); + module.setViews(transSetToList(views)); + module.setDiagrams(transSetToList(diagrams)); + module.fillEntitiesRowNo(); + module.fillDictsRowNo(); + + return module; + } + + /** + * 将set转成list,FOR JDK 8 + * @param setitems + * @return + * @param + */ + protected List transSetToList(Set setitems){ + List result = new ArrayList<>(); + for (T t :setitems){ + result.add(t); + } + return result; + } + + /** + * 将文件转换为json文件 + * @param sinerFile + * @return + * @throws IOException + */ + protected String parseFile(File sinerFile) throws IOException { + String jsonText = null; + try(InputStream inputStream = FileKit.openInputStream(sinerFile)) { + jsonText = IOKit.toString(inputStream, "UTF-8"); + } catch (IOException e) { + throw e; + } + return jsonText; + } + +} diff --git a/src/main/java/cn/com/chiner/java/model/ColumnHeader.java b/src/main/java/cn/com/chiner/java/model/ColumnHeader.java index 989b873..57360d0 100644 --- a/src/main/java/cn/com/chiner/java/model/ColumnHeader.java +++ b/src/main/java/cn/com/chiner/java/model/ColumnHeader.java @@ -56,4 +56,26 @@ public class ColumnHeader { public void setEnable(Boolean enable) { this.enable = enable; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + ColumnHeader header; + if(o instanceof ColumnHeader){ + header = (ColumnHeader) o; + } + else{ + return false; + } + + if (getRefKey() != null ? !getRefKey().equals(header.getRefKey()) : header.getRefKey() != null) return false; + return getValue() != null ? getValue().equals(header.getValue()) : header.getValue() == null; + } + + @Override + public int hashCode() { + int result = getRefKey() != null ? getRefKey().hashCode() : 0; + result = 31 * result + (getValue() != null ? getValue().hashCode() : 0); + return result; + } } diff --git a/src/main/java/cn/com/chiner/java/model/Dict.java b/src/main/java/cn/com/chiner/java/model/Dict.java index 4934ce7..5dde713 100644 --- a/src/main/java/cn/com/chiner/java/model/Dict.java +++ b/src/main/java/cn/com/chiner/java/model/Dict.java @@ -70,4 +70,29 @@ public class Dict implements Serializable,Cloneable{ public void setItems(List items) { this.items = items; } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + Dict dict; + if(o instanceof Dict){ + dict = (Dict) o; + }else{ + return false; + } + + if (getDefKey() != null ? !getDefKey().equals(dict.getDefKey()) : dict.getDefKey() != null) return false; + if (getDefName() != null ? !getDefName().equals(dict.getDefName()) : dict.getDefName() != null) return false; + if (getIntro() != null ? !getIntro().equals(dict.getIntro()) : dict.getIntro() != null) return false; + return true; + } + + @Override + public int hashCode() { + int result = getDefKey() != null ? getDefKey().hashCode() : 0; + result = 31 * result + (getDefName() != null ? getDefName().hashCode() : 0); + result = 31 * result + (getIntro() != null ? getIntro().hashCode() : 0); + return result; + } } diff --git a/src/test/java/cn/com/chiner/GenXlsxMergeTest.java b/src/test/java/cn/com/chiner/GenXlsxMergeTest.java new file mode 100644 index 0000000..3e003e3 --- /dev/null +++ b/src/test/java/cn/com/chiner/GenXlsxMergeTest.java @@ -0,0 +1,17 @@ +package cn.com.chiner; + +import cn.com.chiner.java.Application; +import org.junit.Test; + +public class GenXlsxMergeTest { + @Test + public void genXlsxMergedTest(){ + String[] args = new String[]{ + "GenExcelMergedImpl", //执行什么命令 + "dataDir=/Users/baodan/develop/isoftstone/product/ifinance/db-script/01_business/01_design", //输入的PDMan文件 + "outFile=/Users/baodan/develop/isoftstone/product/ifinance/db-script/01_business/result-by-"+System.nanoTime()+"simple.xlsx", //输入的PDMan文件 + "out=/Users/baodan/develop/isoftstone/product/ifinance/db-script/01_business/gen-xlsx-simple-"+System.nanoTime()+".json" + }; + Application.main(args); + } +} diff --git a/src/test/java/cn/com/chiner/java/command/impl/GenExcelMergedImplTest.java b/src/test/java/cn/com/chiner/java/command/impl/GenExcelMergedImplTest.java new file mode 100644 index 0000000..7668eb3 --- /dev/null +++ b/src/test/java/cn/com/chiner/java/command/impl/GenExcelMergedImplTest.java @@ -0,0 +1,165 @@ +package cn.com.chiner.java.command.impl; + + +import cn.hutool.core.io.FileUtil; +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({GenExcelMergedImpl.class, LoggerFactory.class}) +public class GenExcelMergedImplTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Mock + Logger logger; + @InjectMocks + private GenExcelMergedImpl genExcelMerged = new GenExcelMergedImpl(); + + @Before + public void setUp() throws Exception { + PowerMockito.mockStatic(LoggerFactory.class); + PowerMockito.when(LoggerFactory.getLogger(GenExcelMergedImpl.class)).thenReturn(logger); + MockitoAnnotations.initMocks(this); + } + + /** + * 必然报错 + * + * @throws Exception + */ + @Test + public void execThrowException() throws Exception { + String dataDir = ""; + String outFile = ""; + String out = ""; + GenExcelMergedImpl spy = PowerMockito.spy(genExcelMerged); + PowerMockito.when(genExcelMerged, "readPdmaJson", dataDir).thenAnswer((m) -> { + List list = new ArrayList<>(); + return list; + }); + try { + thrown.expect(RuntimeException.class); + spy.execjson(dataDir, outFile, out); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 必然成功 + * + * @throws Exception + */ + @Test + public void execjson() throws Exception { + String dataDir = ""; + File file = FileUtil.createTempFile("test", ".xlsx", true); + String outFile = file.getAbsolutePath(); + String out = ""; + GenExcelMergedImpl spy = PowerMockito.spy(genExcelMerged); + PowerMockito.when(genExcelMerged, "readPdmaJson", dataDir).thenAnswer((m) -> { + List list = new ArrayList<>(); + return list; + }); + try { + spy.execjson(dataDir, outFile, out); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + FileUtils.forceDeleteOnExit(new File(outFile)); + } + } + + + @Test + public void testExec() { + GenExcelMergedImpl spy = PowerMockito.spy(genExcelMerged); + String path = "src/test/resources"; + File file = new File(path); + String dataDir = file.getAbsolutePath(); + File excelfile = FileUtil.createTempFile("test", ".xlsx", true); + String outFile = excelfile.getAbsolutePath(); + String out = ""; + Map param = new HashMap<>(); + + param.putIfAbsent("dataDir", dataDir); + param.putIfAbsent("outFile", outFile); + param.putIfAbsent("type", "json"); + param.putIfAbsent("out", ""); + + try { + spy.exec(param); + } catch (IOException e) { + Assert.fail(); + throw new RuntimeException(e); + } finally { + FileUtil.del(outFile); + } + } + + @Test + public void testExecThrowEx() { + GenExcelMergedImpl spy = PowerMockito.spy(genExcelMerged); + String path = "src/test/resources"; + File file = new File(path); + String dataDir = file.getAbsolutePath(); + File excelfile = FileUtil.createTempFile("test", ".xlsx", true); + String outFile = excelfile.getAbsolutePath(); + String out = ""; + Map param = new HashMap<>(); + + param.putIfAbsent("dataDir", dataDir); + param.putIfAbsent("outFile", outFile); + param.putIfAbsent("type", "json"); + param.putIfAbsent("out", ""); + + try { + Mockito.doThrow(new IOException("test")).when(spy).execjson(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + +// PowerMockito.when(genExcelMerged,"execjson",dataDir,outFile,out).thenThrow(Exception.class); + + spy.exec(param); + } catch (IOException e) { + Assert.fail(); + throw new RuntimeException(e); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + FileUtil.del(outFile); + } + } + + @Test + public void readPdmaJson() throws IOException { + GenExcelMergedImpl spy = PowerMockito.spy(genExcelMerged); + String path = "src/test/resources"; + File file = new File(path); + String absolutePath = file.getAbsolutePath(); + List files = spy.readPdmaJson(absolutePath); + Assert.assertNotNull(files); + } + +} \ No newline at end of file -- Gitee