diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/ConstructionServiceImpl.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/ConstructionServiceImpl.java index b16da12..cbd3fa6 100644 --- a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/ConstructionServiceImpl.java +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/ConstructionServiceImpl.java @@ -1,7 +1,6 @@ package com.hnac.hzims.operational.access.service.impl; import cn.afterturn.easypoi.entity.ImageEntity; -import cn.afterturn.easypoi.word.WordExportUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -10,12 +9,12 @@ import com.hnac.hzims.operational.access.entity.OperConstructionEntity; import com.hnac.hzims.operational.access.mapper.ConstructionMapper; import com.hnac.hzims.operational.access.service.ConstructionService; import com.hnac.hzims.operational.access.service.IOperAccessTaskService; +import com.hnac.hzims.operational.access.utils.BaseUtil; import com.hnac.hzims.operational.access.vo.ConstructionVo; import com.hnac.hzims.operational.util.PdfUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; -import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.mp.support.Condition; @@ -28,14 +27,11 @@ import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLEncoder; import java.util.Date; -import java.util.HashMap; import java.util.Map; /** @@ -81,35 +77,15 @@ public class ConstructionServiceImpl extends BaseServiceImpl params = new HashMap<>(); + Map params = BaseUtil.obj2Map(construction); try { params = PdfUtils.objectToMap(construction); }catch (Exception e) { log.error("转换对象失败!"); } String fileName = construction.getCode() + "_" + construction.getOverhaulName() + "_施工日志" + PdfUtils.DOCX_SUFFIX; - XWPFDocument document; - try { - document = WordExportUtil.exportWord07("template/word/constructio_template.docx",params); - } catch (Exception e) { - throw new ServiceException("文件创建失败!"); - } - response.setCharacterEncoding("UTF-8"); - response.setContentType("application/vnd.ms-word"); - ServletOutputStream outputStream; - try { - //设置docx格式 - response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); - //创建一个输出流 - outputStream = response.getOutputStream(); - //写入数据 - document.write(outputStream); - // 关闭 - outputStream.close(); - document.close(); - } catch (IOException e) { - e.printStackTrace(); - } + String templateFile = "template/word/constructio_template.docx"; + BaseUtil.exportDocument(templateFile, params, fileName, "constructionAttachment", response); } @Override diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/OperAccessLibraryServiceImpl.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/OperAccessLibraryServiceImpl.java index 9033366..57daf5f 100644 --- a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/OperAccessLibraryServiceImpl.java +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/service/impl/OperAccessLibraryServiceImpl.java @@ -196,7 +196,7 @@ public class OperAccessLibraryServiceImpl extends BaseServiceImpl params, String fileName,String findName, HttpServletResponse response) { + try { + XWPFDocument document = BaseUtil.fillDocument(templateFile, params,findName); + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/vnd.ms-word"); + ServletOutputStream outputStream; + //设置docx格式 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + //创建一个输出流 + outputStream = response.getOutputStream(); + //写入数据 + document.write(outputStream); + // 关闭 + outputStream.close(); + document.close(); + } catch (Exception e) { + log.error("文件导出异常: {}", e.getMessage()); + } + } + + /** + * word文件导出 + * @param documents doc文件 + * @param savePath 存储路径 + */ + public static void exportWord(List documents, String savePath) { + FileOutputStream out = null; + try { + out = new FileOutputStream(savePath); + for (XWPFDocument document : documents) { + document.write(out); + } + } catch (IOException e) { + log.error("word文件导出异常: {}", e.getMessage()); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + log.error("word文件导出-输出流关闭异常: {}", e.getMessage()); + } + } + } + } + + /** + * 数据写入 + * @param templatePath 模板文件路径 + * @param params 数据参数 + * @return 文件 + */ + public static XWPFDocument fillDocument(String templatePath, Map params, String findName) { + XWPFDocument xwpfDocument = null; + try { + xwpfDocument = WordExportUtil.exportWord07(templatePath, params); + if (StringUtils.isNotEmpty(findName)) { + String findText = params.get(findName).toString(); + if (StringUtils.isNotEmpty(findText)) { + JSONArray jsonArray = JSONObject.parseArray(findText); + for (XWPFTable table : xwpfDocument.getTables()) { + for (int row = 0; row < table.getNumberOfRows(); row++) { + for (int col = 0; col < table.getRow(row).getTableCells().size(); col++) { + XWPFTableCell cell = table.getRow(row).getCell(col); + for (XWPFParagraph p : cell.getParagraphs()) { + Iterator iterator = p.getRuns().iterator(); + while (iterator.hasNext()) { + XWPFRun r = iterator.next(); + String text = r.getText(0); + if (findText.equals(text)) { + r.setText("", 0); // 清除原有文本 + XWPFParagraph paragraph = r.getParagraph(); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + String name = jsonObject.getString("name"); + String url = jsonObject.getString("url"); + String id = paragraph.getDocument().getPackagePart().addExternalRelationship(url, XWPFRelation.HYPERLINK.getRelation()).getId(); + CTHyperlink cLink = paragraph.getCTP().addNewHyperlink(); + cLink.setId(id); + CTText ctText = CTText.Factory.newInstance(); + ctText.setStringValue(name); + CTR ctr = CTR.Factory.newInstance(); + ctr.setTArray(new CTText[]{ctText}); + cLink.setRArray(new CTR[]{ctr}); + if(i tableList = xwpfDocument.getTables(); + if (tableList.size() > 0) { + // 循环表格 + for (XWPFTable table : tableList) { + // 获取表格所有行数 + List rows = table.getRows(); + // 第三行到倒数第二行为需合并区域 + for (int row = 3; row < rows.size() - 1;) { + XWPFTableCell startCell = rows.get(row).getCell(0); + String startText = startCell.getText(); + int index = row + 1; + for (; index < rows.size(); index++) { + XWPFTableCell endCell = rows.get(index).getCell(0); + String endText = endCell.getText(); + if (!startText.equals(endText)) { + break; + } + } + mergeCellsVertically(table, 0, row, index - 1); + mergeCellsVertically(table, 1, row, index - 1); + mergeCellsVertically(table, 4, row, index - 1); + mergeCellsVertically(table, 5, row, index - 1); + row = index; + } + } + } + } + + /** + * word单元格行合并 + * @param table 表格 + * @param col 合并行所在列 + * @param startRow 开始行 + * @param endRow 结束行 + */ + public static void mergeCellsVertically(XWPFTable table, int col, int startRow, int endRow) { + for (int i = startRow; i <= endRow; i++) { + XWPFTableCell cell = table.getRow(i).getCell(col); + if (i == startRow) { + // The first merged cell is set with RESTART merge value + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART); + } else { + // Cells which join (merge) the first one, are set with CONTINUE + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE); + } + } + } + + /** + * 读取本地pdf,这里设置的是预览 + * @param response 响应类 + * @param filePath 文件路径 + */ + public static void readPdf(HttpServletResponse response, String filePath) { + response.reset(); + response.setContentType("application/pdf"); + FileInputStream fileInputStream = null; + OutputStream outputStream = null; + try { + File file = new File(filePath); + fileInputStream = new FileInputStream(file); + outputStream = response.getOutputStream(); + IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream); + response.setHeader("Content-Disposition", + "inline; filename= " + URLEncoder.encode(file.getName(), "UTF-8")); + outputStream.flush(); + } catch (IOException e) { + log.error("本地pdf文件读取异常: {}", e.getMessage()); + } finally { + try { + if (fileInputStream != null) { + fileInputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 对象转map + * @param obj 对象类 + * @return map参数 + */ + public static Map obj2Map(Object obj) { + Map result = new HashMap<>(); + if (ObjectUtil.isNotEmpty(obj) && null != obj.getClass()) { + List fieldList = new ArrayList<>(); + Class clazz = obj.getClass(); + while (clazz != null) { + fieldList.addAll(Arrays.asList(clazz.getDeclaredFields())); + clazz = clazz.getSuperclass(); + } + fieldList.forEach (field -> { + field.setAccessible(true); + Object value; + try { + value = field.get(obj); + } catch (IllegalAccessException e) { + throw new ServiceException("获取属性性出错"); + } + if (value instanceof LocalDateTime) { + value = DateUtil.format((LocalDateTime) value, SafeProductConstant.SAFEPRODUCT_EXPORT_DATE); + } + else if (value instanceof Date) { + value = DateUtil.format((Date) value, SafeProductConstant.SAFEPRODUCT_EXPORT_DATE); + } + result.put(field.getName(),value); + }); + } + return result; + } + + /** + * 图片转字节 + * @param tempImgPath 图片路径 + * @return 图片字节 + */ + public static byte[] imgToByte(String tempImgPath) { + File file = new File(tempImgPath); + byte[] buffer = null; + try { + FileInputStream fis = new FileInputStream(file); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1000); + byte[] b = new byte[1000]; + int n; + while ((n = fis.read(b)) != -1) { + bos.write(b, 0, n); + } + fis.close(); + bos.close(); + buffer = bos.toByteArray(); + } catch (IOException e) { + log.error(e.getMessage()); + } + //删除临时文件 + file.delete(); + return buffer; + } + + /** + * 下载文件 + * @param fileUrl 文件路径 + * @param downloadFileDir 下载路径 + * @return 下载文件路径 + */ + public static String downloadFileByUrl(String fileUrl, String downloadFileDir){ + URL url; + String fileName = null; + try { + url = new URL(fileUrl); + HttpURLConnection connection = (HttpURLConnection)url.openConnection(); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + int responseCode = connection.getResponseCode(); + if (responseCode == 200) { + InputStream inputStream = connection.getInputStream(); + int lastSlashIndex = fileUrl.lastIndexOf("/"); + if (lastSlashIndex > 0) { + fileName = fileUrl.substring(lastSlashIndex+1); + String filePath = downloadFileDir + fileName; + File file = new File(filePath); + if (file.exists()){ + file.delete(); + } + OutputStream outputStream = Files.newOutputStream(file.toPath()); + // 将文件流拷贝到本地处理 + IOUtils.copy(inputStream, outputStream); + } else { + throw new ServiceException("下载文件路径异常:" + downloadFileDir); + } + } + } catch (Exception e) { + throw new ServiceException("文件图片下载失败!"); + } + return fileName; + } +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/EasyExcelWriterFactory.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/EasyExcelWriterFactory.java new file mode 100644 index 0000000..3ba54b8 --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/EasyExcelWriterFactory.java @@ -0,0 +1,55 @@ +package com.hnac.hzims.operational.access.utils; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; + +import java.io.File; +import java.io.OutputStream; +import java.util.List; + +/** + * @author hx + */ +public class EasyExcelWriterFactory { + private int sheetNo = 0; + private ExcelWriter excelWriter = null; + + public EasyExcelWriterFactory(OutputStream outputStream) { + excelWriter = EasyExcel.write(outputStream).build(); + } + + public EasyExcelWriterFactory(File file) { + excelWriter = EasyExcel.write(file).build(); + } + + public EasyExcelWriterFactory(String filePath) { + excelWriter = EasyExcel.write(filePath).build(); + } + + /** + * 链式模板表头写入 + * @param headClazz 表头格式 + * @param data 数据 List 或者List> + * @return + */ + public EasyExcelWriterFactory writeModel(Class headClazz, List data, String sheetName){ + excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(headClazz).build()); + return this; + } + + /** + * 链式自定义表头写入 + * @param head + * @param data 数据 List 或者List> + * @param sheetName + * @return + */ + public EasyExcelWriterFactory write(List> head, List data, String sheetName){ + excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(head).build()); + return this; + } + + public void finish() { + excelWriter.finish(); + } +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelToolListener.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelToolListener.java new file mode 100644 index 0000000..ea51ea8 --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelToolListener.java @@ -0,0 +1,33 @@ +package com.hnac.hzims.operational.access.utils; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Slf4j +@Data +public class ExcelToolListener extends AnalysisEventListener { + + /**保存数据**/ + private List dataList = Collections.synchronizedList(new ArrayList<>()); + + public ExcelToolListener() { + } + + @Override + public void invoke(Object data, AnalysisContext context) { + dataList.add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + log.info("解析完成"); + log.info("------结果集为:{}------", JSONObject.toJSONString(dataList)); + } +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelUtil.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelUtil.java new file mode 100644 index 0000000..7531371 --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/ExcelUtil.java @@ -0,0 +1,411 @@ +package com.hnac.hzims.operational.access.utils; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.EasyExcelFactory; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.write.handler.WriteHandler; +import org.apache.poi.ss.formula.functions.T; +import org.omg.CORBA_2_3.portable.OutputStream; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author hx + */ +public class ExcelUtil { + /** + * 同步无模型读(默认读取sheet0,从第2行开始读) + * @param filePath + * @return + */ + public static List> syncRead(String filePath){ + return EasyExcelFactory.read(filePath).sheet().doReadSync(); + } + + /** + * 同步无模型读(默认表头占一行,从第2行开始读) + * @param filePath + * @param sheetNo sheet页号,从0开始 + * @return + */ + public static List> syncRead(String filePath, Integer sheetNo){ + return EasyExcelFactory.read(filePath).sheet(sheetNo).doReadSync(); + } + + /** + * 同步无模型读(指定sheet和表头占的行数) + * @param inputStream + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return List> + */ + public static List> syncRead(InputStream inputStream, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).doReadSync(); + } + + /** + * 同步无模型读(指定sheet和表头占的行数) + * @param file + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return List> + */ + public static List> syncRead(File file, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).doReadSync(); + } + + /** + * 同步无模型读(指定sheet和表头占的行数) + * @param filePath + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return List> + */ + public static List> syncRead(String filePath, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).doReadSync(); + } + + /** + * 同步按模型读(默认读取sheet0,从第2行开始读) + * @param filePath + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @return + */ + public static List syncReadModel(String filePath, Class clazz){ + return EasyExcelFactory.read(filePath).sheet().head(clazz).doReadSync(); + } + + /** + * 同步按模型读(默认表头占一行,从第2行开始读) + * @param filePath + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @return + */ + public static List syncReadModel(String filePath, Class clazz, Integer sheetNo){ + return EasyExcelFactory.read(filePath).sheet(sheetNo).head(clazz).doReadSync(); + } + + /** + * 同步按模型读(指定sheet和表头占的行数) + * @param inputStream + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static List syncReadModel(InputStream inputStream, Class clazz, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync(); + } + + /** + * 同步按模型读(指定sheet和表头占的行数) + * @param file + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static List syncReadModel(File file, Class clazz, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync(); + } + + /** + * 同步按模型读(指定sheet和表头占的行数) + * @param filePath + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static List syncReadModel(String filePath, Class clazz, Integer sheetNo, Integer headRowNum){ + return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync(); + } + + /** + * 异步无模型读(默认读取sheet0,从第2行开始读) + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param filePath 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static void asyncRead(String filePath, AnalysisEventListener excelListener){ + EasyExcelFactory.read(filePath, excelListener).sheet().doRead(); + } + + /** + * 异步无模型读(默认表头占一行,从第2行开始读) + * @param filePath 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param sheetNo sheet页号,从0开始 + * @return + */ + public static void asyncRead(String filePath, AnalysisEventListener excelListener, Integer sheetNo){ + EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).doRead(); + } + + /** + * 异步无模型读(指定sheet和表头占的行数) + * @param inputStream + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static void asyncRead(InputStream inputStream, AnalysisEventListener excelListener, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(inputStream, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 异步无模型读(指定sheet和表头占的行数) + * @param file + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static void asyncRead(File file, AnalysisEventListener excelListener, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(file, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 异步无模型读(指定sheet和表头占的行数) + * @param filePath + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + * @return + */ + public static void asyncRead(String filePath, AnalysisEventListener excelListener, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 异步按模型读取(默认读取sheet0,从第2行开始读) + * @param filePath + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + */ + public static void asyncReadModel(String filePath, AnalysisEventListener excelListener, Class clazz){ + EasyExcelFactory.read(filePath, clazz, excelListener).sheet().doRead(); + } + + /** + * 异步按模型读取(默认表头占一行,从第2行开始读) + * @param filePath + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + */ + public static void asyncReadModel(String filePath, AnalysisEventListener excelListener, Class clazz, Integer sheetNo){ + EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).doRead(); + } + + /** + * 异步按模型读取 + * @param inputStream + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + */ + public static void asyncReadModel(InputStream inputStream, AnalysisEventListener excelListener, Class clazz, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(inputStream, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 异步按模型读取 + * @param file + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + */ + public static void asyncReadModel(File file, AnalysisEventListener excelListener, Class clazz, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(file, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 异步按模型读取 + * @param filePath + * @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等 + * @param clazz 模型的类类型(excel数据会按该类型转换成对象) + * @param sheetNo sheet页号,从0开始 + * @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0) + */ + public static void asyncReadModel(String filePath, AnalysisEventListener excelListener, Class clazz, Integer sheetNo, Integer headRowNum){ + EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead(); + } + + /** + * 无模板写文件 + * @param filePath + * @param head 表头数据 + * @param data 表内容数据 + */ + public static void write(String filePath, List> head, List> data){ + EasyExcel.write(filePath).head(head).sheet().doWrite(data); + } + + /** + * 无模板写文件 + * @param filePath + * @param head 表头数据 + * @param data 表内容数据 + * @param sheetNo sheet页号,从0开始 + * @param sheetName sheet名称 + */ + public static void write(String filePath, List> head, List> data, Integer sheetNo, String sheetName){ + EasyExcel.write(filePath).head(head).sheet(sheetNo, sheetName).doWrite(data); + } + + /** + * 根据excel模板文件写入文件 + * @param filePath + * @param templateFileName + * @param headClazz + * @param data + */ + public static void writeTemplate(String filePath, String templateFileName, Class headClazz, List data){ + EasyExcel.write(filePath, headClazz).withTemplate(templateFileName).sheet().doWrite(data); + } + + /** + * 根据excel模板文件写入文件 + * @param filePath + * @param templateFileName + * @param data + */ + public static void writeTemplate(String filePath, String templateFileName, List data){ + EasyExcel.write(filePath).withTemplate(templateFileName).sheet().doWrite(data); + } + + /** + * 按模板写文件 + * @param filePath + * @param headClazz 表头模板 + * @param data 数据 + */ + public static void write(String filePath, Class headClazz, List data){ + EasyExcel.write(filePath, headClazz).sheet().doWrite(data); + } + + /** + * 按模板写文件 + * @param filePath + * @param headClazz 表头模板 + * @param data 数据 + * @param sheetNo sheet页号,从0开始 + * @param sheetName sheet名称 + */ + public static void write(String filePath, Class headClazz, List data, Integer sheetNo, String sheetName){ + EasyExcel.write(filePath, headClazz).sheet(sheetNo, sheetName).doWrite(data); + } + + /** + * 按模板写文件 + * @param filePath + * @param headClazz 表头模板 + * @param data 数据 + * @param writeHandler 自定义的处理器,比如设置table样式,设置超链接、单元格下拉框等等功能都可以通过这个实现(需要注册多个则自己通过链式去调用) + * @param sheetNo sheet页号,从0开始 + * @param sheetName sheet名称 + */ + public static void write(String filePath, Class headClazz, List data, WriteHandler writeHandler, Integer sheetNo, String sheetName){ + EasyExcel.write(filePath, headClazz).registerWriteHandler(writeHandler).sheet(sheetNo, sheetName).doWrite(data); + } + + /** + * 按模板写文件(包含某些字段) + * @param filePath + * @param headClazz 表头模板 + * @param data 数据 + * @param includeCols 过滤包含的字段,根据字段名称过滤 + * @param sheetNo sheet页号,从0开始 + * @param sheetName sheet名称 + */ + public static void writeInclude(String filePath, Class headClazz, List data, Set includeCols, Integer sheetNo, String sheetName){ + EasyExcel.write(filePath, headClazz).includeColumnFiledNames(includeCols).sheet(sheetNo, sheetName).doWrite(data); + } + + /** + * 按模板写文件(排除某些字段) + * @param filePath + * @param headClazz 表头模板 + * @param data 数据 + * @param excludeCols 过滤排除的字段,根据字段名称过滤 + * @param sheetNo sheet页号,从0开始 + * @param sheetName sheet名称 + */ + public static void writeExclude(String filePath, Class headClazz, List data, Set excludeCols, Integer sheetNo, String sheetName){ + EasyExcel.write(filePath, headClazz).excludeColumnFiledNames(excludeCols).sheet(sheetNo, sheetName).doWrite(data); + } + + /** + * 多个sheet页的数据链式写入 + * ExcelUtil.writeWithSheets(outputStream) + * .writeModel(ExcelModel.class, excelModelList, "sheetName1") + * .write(headData, data,"sheetName2") + * .finish(); + * @param outputStream + * @return + */ + public static EasyExcelWriterFactory writeWithSheets(OutputStream outputStream){ + EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(outputStream); + return excelWriter; + } + + /** + * 多个sheet页的数据链式写入 + * ExcelUtil.writeWithSheets(file) + * .writeModel(ExcelModel.class, excelModelList, "sheetName1") + * .write(headData, data,"sheetName2") + * .finish(); + * @param file + * @return + */ + public static EasyExcelWriterFactory writeWithSheets(File file){ + EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(file); + return excelWriter; + } + + /** + * 多个sheet页的数据链式写入 + * ExcelUtil.writeWithSheets(filePath) + * .writeModel(ExcelModel.class, excelModelList, "sheetName1") + * .write(headData, data,"sheetName2") + * .finish(); + * @param filePath + * @return + */ + public static EasyExcelWriterFactory writeWithSheets(String filePath){ + EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(filePath); + return excelWriter; + } + + /** + * 多个sheet页的数据链式写入(失败了会返回一个有部分数据的Excel) + * ExcelUtil.writeWithSheets(response, exportFileName) + * .writeModel(ExcelModel.class, excelModelList, "sheetName1") + * .write(headData, data,"sheetName2") + * .finish(); + * @param response + * @param exportFileName 导出的文件名称 + * @return + */ + public static EasyExcelWriterFactory writeWithSheetsWeb(HttpServletResponse response, String exportFileName) throws IOException{ + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 + String fileName = URLEncoder.encode(exportFileName, "UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(response.getOutputStream()); + return excelWriter; + } +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/HtmlModule.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/HtmlModule.java new file mode 100644 index 0000000..bd988c5 --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/HtmlModule.java @@ -0,0 +1,119 @@ +package com.hnac.hzims.operational.access.utils; + +import java.io.*; +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 专门用来解析生成PDF文档的html自定义模板 + * @author hx + */ +public class HtmlModule { + public static String buildHtml(List modules, String templatePath) throws Exception { + //读取html + String html = readToString(templatePath); + //找到头的部分 + String headHtml = findInString(html, ".*"); + //找到body部分 + String bodyHtml = findInString(html, ".*"); + //处理body部分 + bodyHtml = bodyHtml.substring(6, bodyHtml.length() - 7); + //构造html + StringBuilder htmlStr = new StringBuilder(); + htmlStr.append(""); + htmlStr.append(headHtml); + htmlStr.append(""); + for (int i = 0; i < modules.size(); i++) { + if (i < 1) { + htmlStr.append("
"); + htmlStr.append(buildHtmlBody(bodyHtml, modules.get(i))); + htmlStr.append("
"); + } else { + htmlStr.append("
"); + htmlStr.append(buildHtmlBody(bodyHtml, modules.get(i))); + htmlStr.append("
"); + } + } + htmlStr.append(""); + htmlStr.append(""); + return htmlStr.toString(); + } + /** + * 利用反射把数据注入模板内容中 + * @param bodyHtml + * @param object + * @return + * @throws IllegalAccessException + */ + public static String buildHtmlBody(String bodyHtml, Object object) throws IllegalAccessException { + //获取该对象所有属性 + Field[] fields = object.getClass().getDeclaredFields(); + //设置值 + String result = bodyHtml; + for (Field field : fields) { + field.setAccessible(true); + String key = field.getName(); + Object objValue = field.get(object); + String value = ""; + if (!Objects.isNull(objValue)) { + value = objValue.toString(); + } + result = result.replace("${" + key + "}", value); + } + return result; + } + + /** + * 读取文件到String中,指定以UTF-8格式读取 + * @param filePath + * @return + * @throws IOException + */ + public static String readToString(String filePath) throws IOException { + StringBuffer buffer = new StringBuffer(); + InputStream is = null; + BufferedReader reader = null; + try { + // 用来保存每行读取的内容 + String line; + is = new FileInputStream(filePath); + reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + // 读取第一行 + line = reader.readLine(); + // 如果 line 为空说明读完了 + while (line != null) { + // 将读到的内容添加到 buffer 中 + buffer.append(line); + // 读取下一行 + line = reader.readLine(); + } + } + catch(Exception e) { + e.printStackTrace(); + } + finally { + reader.close(); + is.close(); + } + return buffer.toString(); + } + + /** + * 查找html内容里的标签内容 + * @param html + * @param regex + * @return + */ + public static String findInString(String html, String regex) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(html); + if (matcher.find()) { + return matcher.group(); + } + return null; + } +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TableJsonUtils.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TableJsonUtils.java new file mode 100644 index 0000000..406366f --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TableJsonUtils.java @@ -0,0 +1,230 @@ +package com.hnac.hzims.operational.access.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class TableJsonUtils { + + // 获取日志输出对象 + private static final Logger logger = LoggerFactory.getLogger(TableJsonUtils.class); + + + + /** + * 处理建表语句方法 + * + * @param createTableSql 缩进次数。 + * CREATE TABLE `blade_user` ( + * `id` bigint(64) NOT NULL COMMENT '主键', + * `tenant_id` varchar(12) DEFAULT '000000' COMMENT '租户ID', + * `code` varchar(12) DEFAULT NULL COMMENT '用户编号', + * `account` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号', + * `password` varchar(45) DEFAULT NULL COMMENT '密码', + * `name` varchar(50) DEFAULT NULL COMMENT '昵称', + * `real_name` varchar(10) DEFAULT NULL COMMENT '真名', + * `avatar` varchar(500) DEFAULT NULL COMMENT '头像', + * `email` varchar(45) DEFAULT NULL COMMENT '邮箱', + * `phone` varchar(45) DEFAULT NULL COMMENT '手机', + * `birthday` datetime DEFAULT NULL COMMENT '生日', + * `sex` smallint(6) DEFAULT NULL COMMENT '性别', + * `role_id` varchar(1000) DEFAULT NULL COMMENT '角色id', + * `dept_id` varchar(1000) DEFAULT NULL COMMENT '部门id', + * `post_id` varchar(1000) DEFAULT NULL COMMENT '岗位id', + * `create_user` bigint(64) DEFAULT NULL COMMENT '创建人', + * `create_dept` bigint(64) DEFAULT NULL COMMENT '创建部门', + * `create_time` datetime DEFAULT NULL COMMENT '创建时间', + * `update_user` bigint(64) DEFAULT NULL COMMENT '修改人', + * `update_time` datetime DEFAULT NULL COMMENT '修改时间', + * `status` int(2) DEFAULT NULL COMMENT '状态', + * `is_deleted` int(2) DEFAULT '0' COMMENT '是否已删除', + * `user_type` int(1) DEFAULT '1' COMMENT '0-平台用户,1单站用户,2-集控用户,3-监控用户', + * `data_scope_type` char(1) DEFAULT '2' COMMENT '数据权限类型 0 只看自己 1 本部门 2 本部门级下属 3 从属机构 4 从属机构及下属 5 个人及下属机构', + * `dept_ids` varchar(1000) DEFAULT NULL COMMENT '从属部门id', + * PRIMARY KEY (`id`) USING BTREE + * ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户表' + * @return + */ + public static String createTableSqlProcess(String createTableSql) { + // 回车换行符处理 + createTableSql = createTableSql.replaceAll("\r|\n", ""); + + // 将原始的mysql 建表语句,通过最外层括号分割开三部分,中间部分做处理 + int firstParenthesesIndex = createTableSql.indexOf("("); + int lastParenthesesIndex = createTableSql.lastIndexOf(")"); + if (firstParenthesesIndex >0 && lastParenthesesIndex >0){ + String middle = createTableSql.substring(firstParenthesesIndex+1, lastParenthesesIndex); + //数据类型替换 + String regex = "bit\\([0-9]+\\)|bigint\\([0-9]+\\)|smallint\\([0-9]+\\)|mediumint\\([0-9]+\\)|tinyint\\([0-9]+\\)|int\\([0-9]+\\)"; + middle = middle.replaceAll(regex, "varchar(20)"); + + //时间类型替换为 50 个长度 + middle = middle.replaceAll("datetime", "varchar(50)").replaceAll("timestamp","varchar(50)").replaceAll("DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",""); + middle = middle.replaceAll("AUTO_INCREMENT",""); + // TODO: 其他数据类型也需要替换成varchar, 具体多少位,看数据类型而定 + + // 根据逗号分隔,只保留COMMENT 前面的内容, 规范在注释用不要出现英文逗号 + StringBuffer sb = new StringBuffer(); + String[] fileds = middle.split(","); + for(int i=0; i 0){ + // 只保留注释前面部分 + String needField = fileds[i].substring(0, commentIndex); + // `account` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号', + // 处理特殊语法字符 + needField = processSpecialKeyWord(needField); + sb.append(needField).append(","); + }else { + // TODO:没有注释COMMENT 的,需要区分处理,如果是表设计有写字段没有加注释,需要加入, + // 但是 主键声明这类不需要 PRIMARY KEY (`id`) USING BTREE ,sqlite 中不识别 using 语法 + String needField = fileds[i]; + if (needField.contains("PRIMARY KEY") || needField.contains("USING") || needField.contains("KEY")){ + logger.info("主键语句去除跳过不要"); + }else { + needField = processSpecialKeyWord(needField); + sb.append(needField).append(","); + } + } + } + sb.append(" OFFLINE_FLAG VARCHAR(2) DEFAULT '0')"); + // 拼接完整的建表语句 + createTableSql = createTableSql.substring(0, firstParenthesesIndex+1) + sb; + // 转成成大写 + createTableSql = createTableSql.toUpperCase(); + logger.info("建表语句净化后="+createTableSql); + + }else { + logger.error("建表语句异常情况"); + } + + + return createTableSql; + } + + + + // 处理特殊语法字符(某些mysql语法支持,但是sqlite不支持), 可扩展, + private static String processSpecialKeyWord(String sql){ + + String needField = sql; + // `account` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号', + // 处理特殊语法字符 + if (needField.contains("CHARACTER SET")){ + int characterIndex = needField.indexOf("CHARACTER SET"); + int defaultIndex = needField.indexOf("DEFAULT"); + if (defaultIndex >0){ + needField = needField.substring(0, characterIndex)+" " + needField.substring(defaultIndex); + }else { + needField = needField.substring(0, characterIndex); + } + } + // 处理特殊语法字符 + if (needField.contains("COLLATE")){ + int characterIndex = needField.indexOf("COLLATE"); + int defaultIndex = needField.indexOf("DEFAULT"); + if (defaultIndex >0){ + needField = needField.substring(0, characterIndex)+" " + needField.substring(defaultIndex); + }else { + needField = needField.substring(0, characterIndex); + } + } + return needField; + } + + + + /** + * 单位缩进字符串。 + */ + private static final String SPACE = " "; + /** + * 生成.json格式文件 + */ + public static boolean createJsonFile(String jsonString, String filePath, String fileName) { + // 标记文件生成是否成功 + boolean flag = true; + + // 拼接文件完整路径 + String fullPath = filePath + File.separator + fileName + ".json"; + + // 生成json格式文件 + try { + // 保证创建一个新文件 + File file = new File(fullPath); + if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录 + file.getParentFile().mkdirs(); + } + if (file.exists()) { // 如果已存在,删除旧文件 + file.delete(); + } + file.createNewFile(); + + if(jsonString.indexOf("'")!=-1){ + //将单引号转义一下,因为JSON串中的字符串类型可以单引号引起来的 + jsonString = jsonString.replaceAll("'", "\\'"); + } + if(jsonString.indexOf("\"")!=-1){ + //将双引号转义一下,因为JSON串中的字符串类型可以单引号引起来的 + jsonString = jsonString.replaceAll("\"", "\\\""); + } + + if(jsonString.indexOf("\r\n")!=-1){ + //将回车换行转换一下,因为JSON串中字符串不能出现显式的回车换行 + jsonString = jsonString.replaceAll("\r\n", "\\u000d\\u000a"); + } + if(jsonString.indexOf("\n")!=-1){ + //将换行转换一下,因为JSON串中字符串不能出现显式的换行 + jsonString = jsonString.replaceAll("\n", "\\u000a"); + } + + // 格式化json字符串 +// jsonString = this.formatJson(jsonString); + + // 将格式化后的字符串写入文件 + Writer write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); + write.write(jsonString); + write.flush(); + write.close(); + } catch (Exception e) { + flag = false; + e.printStackTrace(); + } + + // 返回是否成功的标记 + return flag; + } + + + + /** + * 离线文件上传后,各个服务解压后读取自己要的json文件 + * @param fileName + * @return + */ + public static String readJsonFile(String fileName) { + String jsonStr = ""; + try { + File jsonFile = new File(fileName); + FileReader fileReader = new FileReader(jsonFile); + Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8); + int ch = 0; + StringBuffer sb = new StringBuffer(); + while ((ch = reader.read()) != -1) { + sb.append((char) ch); + } + fileReader.close(); + reader.close(); + jsonStr = sb.toString(); + return jsonStr; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + +} diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TimeUtils.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TimeUtils.java new file mode 100644 index 0000000..4b4c22f --- /dev/null +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/access/utils/TimeUtils.java @@ -0,0 +1,194 @@ +package com.hnac.hzims.operational.access.utils; + +import org.springblade.core.tool.utils.DateUtil; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +public class TimeUtils { + + private static int sheet1NowRow, sheet2NowRow; + + + /** + * 相差时数 + * + * @param endDate + * @param nowDate + * @return + * @author ty + */ + public static Long getDifferTime(Date nowDate, Date endDate) { + long nh = 1000 * 60 * 60L; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少小时 + long hour = diff / nh; + return hour; + } + + public static String getYear(Integer year) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为1(即一月) + calendar.set(Calendar.MONTH, Calendar.JANUARY); + // 设置日期为1 + calendar.set(Calendar.DATE, 1); + // 设置时间为0点0分0秒 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + String start = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 00:00:00"; + return start; + } + + public static String getYearEnd(Integer year) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为12(即十二月) + calendar.set(Calendar.MONTH, Calendar.DECEMBER); + // 设置日期为31 + calendar.set(Calendar.DATE, 31); + String end = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 00:00:00"; + return end; + } + public static String getYearEndV2(Integer year) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为12(即十二月) + calendar.set(Calendar.MONTH, Calendar.DECEMBER); + // 设置日期为31 + calendar.set(Calendar.DATE, 31); + String end = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 23:59:59"; + return end; + } + + public static String getMonthStart(Integer year, Integer mon) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份 + calendar.set(Calendar.MONTH,mon-1); + // 设置日期为1 + calendar.set(Calendar.DATE, 1); + String start = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 00:00:00"; + return start; + } + + public static String getMonthEnd(Integer year, Integer mon) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为1(即一月) + calendar.set(Calendar.MONTH, mon); + calendar.set(Calendar.DAY_OF_MONTH, 1); + // 将日期对象减去一天,即为当月的最后一天 + calendar.add(Calendar.DAY_OF_MONTH, -1); + String end = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 00:00:00"; + return end; + } + public static String getMonthEndV2(Integer year, Integer mon) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为1(即一月) + calendar.set(Calendar.MONTH, mon); + calendar.set(Calendar.DAY_OF_MONTH, 1); + // 将日期对象减去一天,即为当月的最后一天 + calendar.add(Calendar.DAY_OF_MONTH, -1); + String end = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE) + " 23:59:59"; + return end; + } + public static List getListByYear(Integer year) { + List monthList=new ArrayList<>(); + for (int i = 0; i <12; i++) { + // 创建一个Calendar对象 + Calendar calendar = Calendar.getInstance(); + // 设置年份 + calendar.set(Calendar.YEAR, year); + // 设置月份为1(即一月) + calendar.set(Calendar.MONTH, i); + calendar.set(Calendar.DAY_OF_MONTH, 1); + // 将日期对象减去一天,即为当月的最后一天 + String mon = DateUtil.format(calendar.getTime(), DateUtil.PATTERN_DATE); + + monthList.add(mon); + } + return monthList; + } + public static List getListByYearMon(Integer year,Integer mon) { + List monthList=new ArrayList<>(); + for (int i = 0; i