diff --git a/report-core/pom.xml b/report-core/pom.xml index ec175901..69abc8c3 100644 --- a/report-core/pom.xml +++ b/report-core/pom.xml @@ -105,6 +105,33 @@ 1.18.10 true + + + com.itextpdf + itextpdf + 5.5.13.2 + + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.poi + poi + 4.1.2 + + + org.apache.poi + poi-ooxml + 4.1.2 + + + org.apache.poi + poi-ooxml-schemas + 4.1.2 + diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java new file mode 100644 index 00000000..b0efbc6e --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java @@ -0,0 +1,73 @@ +package com.anjiplus.template.gaea.business.enums; + +/** + * @author zhouhang + * @description EXCEL居中方式 + * @date 2021/4/26 + */ +public enum ExcelCenterStyleEnum { + /** + * 左对齐 + */ + LEFT((short) 1, 1, "左对齐"), + /** + * 右对齐 + */ + RIGHT((short) 3, 2, "右对齐"), + /** + * 居中 + */ + CENTER((short) 2, 0, "居中"), + ; + + /** + * excel居中code + */ + private final short excelCode; + + /** + * 在线文档居中code + */ + private final Integer onlineExcelCode; + + /** + * 名称 + */ + private final String name; + + + public Integer getOnlineExcelCode() { + return onlineExcelCode; + } + + public String getName() { + return name; + } + + public short getExcelCode() { + return excelCode; + } + + ExcelCenterStyleEnum(short excelCode, Integer onlineExcelCode, String name) { + this.excelCode = excelCode; + this.onlineExcelCode = onlineExcelCode; + this.name = name; + } + + /** + * @param code excel居中样式code + * @return Enum_ExcelCenterStyle + * @description 根据excel居中样式获取在线文档居中样式 + * @author zhouhang + * @date 2021/4/26 + */ + public static ExcelCenterStyleEnum getExcelCenterStyleByExcelCenterCode(short code) { + for (ExcelCenterStyleEnum value : ExcelCenterStyleEnum.values()) { + if (code == value.getExcelCode()) { + return value; + } + } + return CENTER; + } + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java new file mode 100644 index 00000000..6b01a17e --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java @@ -0,0 +1,30 @@ +package com.anjiplus.template.gaea.business.enums; + +/** + * Created by raodeming on 2021/9/3. + */ +public enum ExportTypeEnum { + + /**gaea_excel*/ + GAEA_TEMPLATE_EXCEL("gaea_template_excel", "gaea_template_excel"), + /**gaea_pdf*/ + GAEA_TEMPLATE_PDF("gaea_template_pdf", "gaea_template_pdf"), + ; + + private String codeValue; + private String codeDesc; + + private ExportTypeEnum(String codeValue, String codeDesc) { + this.codeValue = codeValue; + this.codeDesc = codeDesc; + } + + public String getCodeValue() { + return this.codeValue; + } + + public String getCodeDesc() { + return this.codeDesc; + } + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java index bea91d96..a5b293f5 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java @@ -57,6 +57,12 @@ public class TokenFilter implements Filter { HttpServletResponse response = (HttpServletResponse) servletResponse; String uri = request.getRequestURI(); + //OPTIONS直接放行 + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + filterChain.doFilter(request, response); + return; + } + if (SLASH.equals(uri)) { response.sendRedirect("/index.html"); return; diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java index d34dbf62..4c8925db 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java @@ -74,7 +74,7 @@ public class ReportDashboardController { * @return */ @GetMapping("/export") - @Permission(code = "view", name = "导出大屏") + @Permission(code = "export", name = "导出大屏") public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, @RequestParam("reportCode") String reportCode, @RequestParam(value = "showDataSet",required = false, defaultValue = "1") Integer showDataSet) { return reportDashboardService.exportDashboard(request, response, reportCode, showDataSet); @@ -87,7 +87,7 @@ public class ReportDashboardController { * @return */ @PostMapping("/import/{reportCode}") - @Permission(code = "design", name = "导入大屏") + @Permission(code = "import", name = "导入大屏") public ResponseBean importDashboard(@RequestParam("file") MultipartFile file, @PathVariable("reportCode") String reportCode) { reportDashboardService.importDashboard(file, reportCode); return ResponseBean.builder().build(); diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dataset/controller/dto/DataSetDto.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dataset/controller/dto/DataSetDto.java index 06d4bc29..c0722be1 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dataset/controller/dto/DataSetDto.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dataset/controller/dto/DataSetDto.java @@ -55,4 +55,7 @@ public class DataSetDto extends GaeaBaseDTO implements Serializable { private Set setParamList; + /**指定字段*/ + private String fieldLabel; + } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java index 7bfd7d1d..fed43689 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java @@ -99,7 +99,7 @@ public class GaeaFileServiceImpl implements GaeaFileService { String newFileName = fileId + suffixName; // 本地文件保存路径 String filePath = dictPath + newFileName; - String urlPath = fileDownloadPath + java.io.File.separator + fileId; + String urlPath = fileDownloadPath + "/" + fileId; GaeaFile gaeaFile = new GaeaFile(); gaeaFile.setFilePath(filePath); diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java index b0d871b0..f0cfd30a 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java @@ -11,7 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** - * TODO * * @author chenkening * @date 2021/3/26 10:35 @@ -31,11 +30,12 @@ public class ReportServiceImpl implements ReportService { @Override public void delReport(ReportDto reportDto) { deleteById(reportDto.getId()); + //删除gaea_report_excel、gaea_report_dashboard、gaea_report_dashboard_widget + //... } @Override public void processBeforeOperation(Report entity, BaseOperationEnum operationEnum) throws BusinessException { - //目前只有大屏一种类型 - entity.setReportType("report_screen"); + } } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/ReportExcelController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/ReportExcelController.java new file mode 100644 index 00000000..21273693 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/ReportExcelController.java @@ -0,0 +1,78 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.controller; + +import com.anji.plus.gaea.annotation.Permission; +import com.anji.plus.gaea.annotation.log.GaeaAuditLog; +import com.anji.plus.gaea.bean.ResponseBean; +import com.anji.plus.gaea.code.ResponseCode; +import com.anji.plus.gaea.curd.controller.GaeaBaseController; +import com.anji.plus.gaea.curd.service.GaeaBaseService; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.ReportExcelDto; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.param.ReportExcelParam; +import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel; +import com.anjiplus.template.gaea.business.modules.reportexcel.service.ReportExcelService; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @author chenkening + * @date 2021/4/13 15:12 + */ +@RestController +@Api(tags = "报表表格管理") +@Permission(code = "excelManage", name = "报表管理") +@RequestMapping("/reportExcel") +public class ReportExcelController extends GaeaBaseController { + + @Autowired + private ReportExcelService reportExcelService; + + @Override + public GaeaBaseService getService() { + return reportExcelService; + } + + @Override + public ReportExcel getEntity() { + return new ReportExcel(); + } + + @Override + public ReportExcelDto getDTO() { + return new ReportExcelDto(); + } + + @GetMapping("/detailByReportCode/{reportCode}") + @Permission(code = "query", name = "详情") + @GaeaAuditLog(pageTitle = "详情") + public ResponseBean detailByReportCode(@PathVariable String reportCode) { + ReportExcelDto reportExcelDto = reportExcelService.detailByReportCode(reportCode); + return ResponseBean.builder().data(reportExcelDto).build(); + } + + @PostMapping("/preview") + @Permission(code = "view", name = "预览") + @GaeaAuditLog(pageTitle = "预览") + public ResponseBean preview(@RequestBody ReportExcelDto reportExcelDto) { + ReportExcelDto result = reportExcelService.preview(reportExcelDto); + return ResponseBean.builder().data(result).build(); + } + + + @PostMapping("/exportExcel") + @Permission(code = "export", name = "导出") + @GaeaAuditLog(pageTitle = "报表导出") + public ResponseBean exportExcel(@RequestBody ReportExcelDto reportExcelDto) { + + return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE) + .data(reportExcelService.exportExcel(reportExcelDto)) + .message("导出成功,请稍后在文件管理中查看").build(); + } + +// @PostMapping("/exportPdf") +// public ResponseBean exportPdf(@RequestBody ReportExcelDto reportExcelDto) { +// reportExcelService.exportPdf(reportExcelDto); +// return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE) +// .build(); +// } +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/GridRecordDataModel.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/GridRecordDataModel.java new file mode 100644 index 00000000..b7041439 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/GridRecordDataModel.java @@ -0,0 +1,58 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto; + + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.util.List; + +/** + * 存储对象类 + * + * @author Administrator + */ +@Data +public class GridRecordDataModel { + /** + * 记录序列 + */ + Long id; + /** + * 文档ID + */ + String list_id; + /** + * 本记录的行_列 + */ + String row_col; + /** + * sheet序号 + */ + String index; + /** + * 状态是否当前sheet页 + */ + Integer status; + /** + * 块编号 第一块 fblock + */ + String block_id; + /** + * json串 + */ + JSONObject json_data; + /** + * 排序位置 + */ + Integer order; + /** + * 是否删除 + */ + Integer is_delete; + + /** + * sheet页数据 未编号分组 + */ + List dataList; + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/ReportExcelDto.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/ReportExcelDto.java new file mode 100644 index 00000000..df92b09f --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/dto/ReportExcelDto.java @@ -0,0 +1,61 @@ + +package com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto; + +import com.anji.plus.gaea.curd.dto.GaeaBaseDTO; +import lombok.Data; + +import java.io.Serializable; + + +/** + * @author chenkening + * @date 2021/4/13 15:12 + */ +@Data +public class ReportExcelDto extends GaeaBaseDTO implements Serializable { + /** + * 报表名称 + */ + private String reportName; + + /** + * 报表编码 + */ + private String reportCode; + + /** + * 数据集编码,以|分割 + */ + private String setCodes; + + /** + * 分组 + */ + private String reportGroup; + + /** + * 数据集查询参数 + */ + private String setParam; + + /** + * 报表json字符串 + */ + private String jsonStr; + + /** + * 报表类型 + */ + private String reportType; + + /** + * 数据总计 + */ + private long total; + + /** + * 导出类型 + */ + private String exportType; + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/param/ReportExcelParam.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/param/ReportExcelParam.java new file mode 100644 index 00000000..13202587 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/controller/param/ReportExcelParam.java @@ -0,0 +1,18 @@ + +package com.anjiplus.template.gaea.business.modules.reportexcel.controller.param; + +import com.anji.plus.gaea.curd.params.PageParam; +import lombok.Data; + +import java.io.Serializable; + + +/** + * @author chenkening + * @date 2021/4/13 15:12 + */ +@Data +public class ReportExcelParam extends PageParam implements Serializable { + + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/ReportExcelMapper.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/ReportExcelMapper.java new file mode 100644 index 00000000..422b83f8 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/ReportExcelMapper.java @@ -0,0 +1,11 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.dao; + +import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper; +import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel; + +/** + * @author chenkening + * @date 2021/4/13 15:11 + */ +public interface ReportExcelMapper extends GaeaBaseMapper { +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/entity/ReportExcel.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/entity/ReportExcel.java new file mode 100644 index 00000000..2fa43ec7 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/dao/entity/ReportExcel.java @@ -0,0 +1,33 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity; + +import com.anji.plus.gaea.curd.entity.GaeaBaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author chenkening + * @date 2021/4/13 15:11 + */ +@TableName(value = "gaea_report_excel") +@Data +public class ReportExcel extends GaeaBaseEntity { + + @ApiModelProperty(value = "报表编码") + private String reportCode; + + @ApiModelProperty(value = "数据集编码,以|分割") + private String setCodes; + + @ApiModelProperty(value = "数据集查询参数") + private String setParam; + + @ApiModelProperty(value = "报表json字符串") + private String jsonStr; + + @ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG") + private Integer enableFlag; + + @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG") + private Integer deleteFlag; +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/ReportExcelService.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/ReportExcelService.java new file mode 100644 index 00000000..0bceb4b3 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/ReportExcelService.java @@ -0,0 +1,43 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.service; + + +import com.anji.plus.gaea.curd.service.GaeaBaseService; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.ReportExcelDto; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.param.ReportExcelParam; +import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel; + +/** + * TODO + * + * @author chenkening + * @date 2021/4/13 15:14 + */ +public interface ReportExcelService extends GaeaBaseService { + + /** + * 根据报表编码查询详情 + * + * @param reportCode + * @return + */ + ReportExcelDto detailByReportCode(String reportCode); + + /** + * 报表预览 + * + * @param reportExcelDto + * @return + */ + ReportExcelDto preview(ReportExcelDto reportExcelDto); + + + /** + * 导出为excel + * + * @param reportExcelDto + * @return + */ + Boolean exportExcel(ReportExcelDto reportExcelDto); + +// Boolean exportPdf(ReportExcelDto reportExcelDto); +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java new file mode 100644 index 00000000..21117400 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java @@ -0,0 +1,362 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.anji.plus.gaea.constant.BaseOperationEnum; +import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper; +import com.anji.plus.gaea.exception.BusinessException; +import com.anji.plus.gaea.utils.GaeaAssert; +import com.anji.plus.gaea.utils.GaeaBeanUtils; +import com.anjiplus.template.gaea.business.code.ResponseCode; +import com.anjiplus.template.gaea.business.enums.ExportTypeEnum; +import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.DataSetDto; +import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.OriginalDataDto; +import com.anjiplus.template.gaea.business.modules.dataset.service.DataSetService; +import com.anjiplus.template.gaea.business.modules.file.dao.GaeaFileMapper; +import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile; +import com.anjiplus.template.gaea.business.modules.report.dao.ReportMapper; +import com.anjiplus.template.gaea.business.modules.report.dao.entity.Report; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.ReportExcelDto; +import com.anjiplus.template.gaea.business.modules.reportexcel.dao.ReportExcelMapper; +import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel; +import com.anjiplus.template.gaea.business.modules.reportexcel.service.ReportExcelService; +import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsSheetUtil; +import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.*; +import java.util.*; + +/** + * TODO + * + * @author chenkening + * @date 2021/4/13 15:14 + */ +@Service +public class ReportExcelServiceImpl implements ReportExcelService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private ReportExcelMapper reportExcelMapper; + + @Autowired + private DataSetService dataSetService; + + + @Autowired + private ReportMapper reportMapper; + + @Value("${customer.file.dist-path:''}") + private String dictPath; + + @Value("${customer.file.downloadPath:''}") + private String fileDownloadPath; + + @Autowired + private GaeaFileMapper gaeaFileMapper; + + + @Override + public GaeaBaseMapper getMapper() { + return reportExcelMapper; + } + + @Override + public ReportExcelDto detailByReportCode(String reportCode) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("report_code", reportCode); + ReportExcel reportExcel = reportExcelMapper.selectOne(queryWrapper); + if (reportExcel != null) { + ReportExcelDto dto = new ReportExcelDto(); + BeanUtils.copyProperties(reportExcel, dto); + return dto; + } + return null; + } + + /** + * 操作前处理 + * + * @param entity 前端传递的对象 + * @param operationEnum 操作类型 + * @throws BusinessException 阻止程序继续执行或回滚事务 + */ + @Override + public void processBeforeOperation(ReportExcel entity, BaseOperationEnum operationEnum) throws BusinessException { + if (operationEnum.equals(BaseOperationEnum.INSERT)) { + String reportCode = entity.getReportCode(); + ReportExcel report = this.selectOne("report_code", reportCode); + if (null != report) { + this.deleteById(report.getId()); + } + } + } + + /** + * 报表预览 + */ + @Override + public ReportExcelDto preview(ReportExcelDto reportExcelDto) { + // 根据id查询 报表详情 + ReportExcel reportExcel = selectOne("report_code", reportExcelDto.getReportCode()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("report_code", reportExcelDto.getReportCode()); + Report report = reportMapper.selectOne(queryWrapper); + GaeaAssert.notNull(reportExcel, ResponseCode.RULE_CONTENT_NOT_EXIST, "reportExcel"); + String setParam = reportExcelDto.getSetParam(); + + GaeaBeanUtils.copyAndFormatter(reportExcel, reportExcelDto); + if (StringUtils.isNotBlank(setParam)) { + reportExcelDto.setSetParam(setParam); + } + reportExcelDto.setReportName(report.getReportName()); + // 数据集解析 + String jsonStr = analysisReportData(reportExcelDto); + reportExcelDto.setJsonStr(jsonStr); +// reportExcelDto.setTotal(jsonObject.getJSONObject("rows").size()); + return reportExcelDto; + } + + @Override + public Boolean exportExcel(ReportExcelDto reportExcelDto) { + String reportCode = reportExcelDto.getReportCode(); + String exportType = reportExcelDto.getExportType(); + logger.error("导出..."); + if (exportType.equals(ExportTypeEnum.GAEA_TEMPLATE_EXCEL.getCodeValue())) { + ReportExcelDto report = detailByReportCode(reportCode); + reportExcelDto.setJsonStr(report.getJsonStr()); + String jsonStr = analysisReportData(reportExcelDto); + List lists=(List ) JSON.parse(jsonStr); + OutputStream out; + try { + String fileId = UUID.randomUUID().toString(); + String filePath = dictPath + File.separator + fileId + ".xlsx"; + String urlPath = fileDownloadPath + java.io.File.separator + fileId; + + GaeaFile gaeaFile = new GaeaFile(); + gaeaFile.setFilePath(filePath); + gaeaFile.setFileId(fileId); + gaeaFile.setUrlPath(urlPath); + gaeaFile.setFileType("xlsx"); + gaeaFile.setFileInstruction(reportCode + ".xlsx"); + + out = new FileOutputStream(filePath); + XlsUtil.exportXlsFile(out, true, lists); + + gaeaFileMapper.insert(gaeaFile); + logger.info("导出成功:{}", gaeaFile); + } catch (IOException e) { + logger.error("导出失败", e); + } + } + return true; + } + + /** + * 解析报表数据,动态插入列表数据和对象数据 + */ + private String analysisReportData(ReportExcelDto reportExcelDto) { + + String jsonStr = reportExcelDto.getJsonStr(); + String setParam = reportExcelDto.getSetParam(); + List dbObjectList = (List) JSON.parse(jsonStr); + + if (dbObjectList != null && dbObjectList.size() > 0) { + for (int x = 0; x < dbObjectList.size(); x++) { + analysisSheetCellData(dbObjectList.get(x), setParam); + } + } + //fastjson $ref 循环引用 + return JSONObject.toJSONString(dbObjectList, SerializerFeature.DisableCircularReferenceDetect); + } + + /** + * 解析单sheet data + * + * @param dbObject + */ + private void analysisSheet(JSONObject dbObject, String setParma) { + //data是一个二维数组 + if (dbObject.containsKey("data") && null != dbObject.get("data")) { + List data = (List) dbObject.get("data"); + + + //行 + for (int r = 0; r < data.size(); r++) { + JSONArray jsonArray = data.get(r); + //列 + for (int c = 0; c < jsonArray.size(); c++) { + //单元格 + JSONObject cell = jsonArray.getJSONObject(c); + if (null != cell && cell.containsKey("v") && StringUtils.isNotBlank(cell.getString("v"))) { + String v = cell.getString("v"); + DataSetDto dataSet = getDataSet(v, setParma); + if (null != dataSet) { + OriginalDataDto originalDataDto = dataSetService.getData(dataSet); + if (null != originalDataDto.getData()) { + if (originalDataDto.getData().size() == 1) { + //对象 + JSONObject jsonObject = originalDataDto.getData().get(0); + String fieldLabel = jsonObject.getString(dataSet.getFieldLabel()); + + String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + dbObject.getJSONArray("data").getJSONArray(r).getJSONObject(c).put("v", replace); + dbObject.getJSONArray("data").getJSONArray(r).getJSONObject(c).put("m", replace); + + } else { + //集合 + JSONObject jsonObject = originalDataDto.getData().get(0); + String fieldLabel = jsonObject.getString(dataSet.getFieldLabel()); + + String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + dbObject.getJSONArray("data").getJSONArray(r).getJSONObject(c).put("v", replace); + dbObject.getJSONArray("data").getJSONArray(r).getJSONObject(c).put("m", replace); + } + } + + } + } + + + + } + } + + + System.out.println("aaaa"); + + + } + + + } + + /** + * 解析单sheet celldata + * + * @param dbObject + */ + private void analysisSheetCellData(JSONObject dbObject, String setParam) { + //清空data值 + dbObject.remove("data"); + //celldata是一个一维数组 + if (dbObject.containsKey("celldata") && null != dbObject.get("celldata")) { + List celldata = new ArrayList<>(); + celldata.addAll((List) dbObject.get("celldata")); + // 遍历已存在的单元格,查看是否存在动态参数 + for (int i = 0; i < celldata.size(); i++) { + //单元格对象 + JSONObject cellObj = celldata.get(i); + //fastjson深拷贝问题 + String cellStr = cellObj.toJSONString(); + + //行号 + Integer r = cellObj.getInteger("r"); + //列号 + Integer c = cellObj.getInteger("c"); + JSONObject cell = cellObj.getJSONObject("v"); + if (null != cell && cell.containsKey("v") && StringUtils.isNotBlank(cell.getString("v"))) { + String v = cell.getString("v"); + DataSetDto dataSet = getDataSet(v, setParam); + if (null != dataSet) { + OriginalDataDto originalDataDto = dataSetService.getData(dataSet); + if (null != originalDataDto.getData()) { + List data = originalDataDto.getData(); + + for (int j = 0; j < data.size(); j++) { + if (j == 0) { + //处理当前行 + //第一行,作为渲染参照数据 + JSONObject jsonObject = data.get(j); + String fieldLabel = jsonObject.getString(dataSet.getFieldLabel()); + + String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + dbObject.getJSONArray("celldata").getJSONObject(i).getJSONObject("v").put("v", replace); + dbObject.getJSONArray("celldata").getJSONObject(i).getJSONObject("v").put("m", replace); + } else { + //新增的行数据 + JSONObject addCell = data.get(j); + //字段 + String fieldLabel = addCell.getString(dataSet.getFieldLabel()); + String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + + //转字符串,解决深拷贝问题 + JSONObject addCellData = JSONObject.parseObject(cellStr); + + addCellData.put("r", r + j); + addCellData.put("c", c); + addCellData.getJSONObject("v").put("v", replace); + addCellData.getJSONObject("v").put("m", replace); + dbObject.getJSONArray("celldata").add(addCellData); + + } + + } + + } + + } + } + } + + } + + + } + + + /** + * 解析 #{xxxx.xxxxx} 数据 + * @param v + * @return + */ + private DataSetDto getDataSet(String v, String setParam) { + + DataSetDto dto = new DataSetDto(); + if (v.contains("#{") && v.contains("}")) { + int start = v.indexOf("#{") + 2; + int end = v.indexOf("}"); + if (start < end) { + String substring = v.substring(start, end); + if (substring.contains(".")) { + String[] split = substring.split("\\."); + dto.setSetCode( split[0]); + dto.setFieldLabel(split[1]); + getContextData(setParam, dto); + return dto; + } + } + } + return null; + } + + /** + * 动态参数替换 + * @param setParam + * @param dto + */ + private void getContextData(String setParam, DataSetDto dto) { + if (StringUtils.isNotBlank(setParam)) { + JSONObject setParamJson = JSONObject.parseObject(setParam); + Map map = new HashMap<>(); + // 查询条件 + if (setParamJson.containsKey(dto.getSetCode())) { + JSONObject paramCondition = setParamJson.getJSONObject(dto.getSetCode()); + paramCondition.forEach(map::put); + } + dto.setContextData(map); + } + } + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ColorUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ColorUtil.java new file mode 100644 index 00000000..5e9037e3 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ColorUtil.java @@ -0,0 +1,134 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFPalette; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Color; +import org.apache.poi.xssf.usermodel.XSSFColor; + + +/** + * 来自:https://github.com/mengshukeji/LuckysheetServer + * + * @author Administrator + */ +@Slf4j +public class ColorUtil { + + private static final String S = "0123456789ABCDEF"; + + public static Short getColorByStr(String colorStr) { + HSSFWorkbook workbook = new HSSFWorkbook(); + HSSFPalette palette = workbook.getCustomPalette(); + + if (colorStr.toLowerCase().startsWith("rgb")) { + colorStr = colorStr.toLowerCase().replace("rgb(", "").replace(")", ""); + String[] colors = colorStr.split(","); + if (colors.length == 3) { + try { + int red = Integer.parseInt(colors[0].trim(), 16); + int green = Integer.parseInt(colors[1].trim(), 16); + int blue = Integer.parseInt(colors[2].trim(), 16); + + HSSFColor hssfColor = palette.findSimilarColor(red, green, blue); + return hssfColor.getIndex(); + } catch (Exception ex) { + log.error(ex.toString()); + return null; + } + } + return null; + } + + if (colorStr.equals("#000")) { + colorStr = "#000000"; + } + if (colorStr != null && colorStr.length() >= 6) { + try { + if (colorStr.length() == 8) { + colorStr = colorStr.substring(2); + } + if (colorStr.length() == 7) { + colorStr = colorStr.substring(1); + } + String str2 = colorStr.substring(0, 2); + String str3 = colorStr.substring(2, 4); + String str4 = colorStr.substring(4, 6); + int red = Integer.parseInt(str2, 16); + int green = Integer.parseInt(str3, 16); + int blue = Integer.parseInt(str4, 16); + + HSSFColor hssfColor = palette.findSimilarColor(red, green, blue); + return hssfColor.getIndex(); + } catch (Exception ex) { + log.error(ex.toString()); + return null; + } + } + return null; + } + + /** + * RGB转换成十六进制 + * + * @param r + * @param g + * @param b + * @return + */ + public static String convertRGBToHex(short r, short g, short b) { + String hex = ""; + if (r >= 0 && r < 256 && g >= 0 && g < 256 && b >= 0 && b < 256) { + int x, y, z; + x = r % 16; + r = (short) ((r - x) / 16); + y = g % 16; + g = (short) ((g - y) / 16); + z = b % 16; + b = (short) ((b - z) / 16); + hex = "#" + S.charAt(r) + S.charAt(x) + S.charAt(g) + S.charAt(y) + S.charAt(b) + S.charAt(z); + } + return hex; + } + + /** + * @param cell 单元格 + * @return 转换RGB颜色值 + * @description tint转换RBG + * @author zhouhang + * @date 2021/4/26 + */ + public static String getFillColorHex(Cell cell) { + String fillColorString = null; + if (cell != null) { + CellStyle cellStyle = cell.getCellStyle(); + Color color = cellStyle.getFillForegroundColorColor(); + if (color instanceof XSSFColor) { + XSSFColor xssfColor = (XSSFColor) color; + byte[] argb = xssfColor.getARGB(); + fillColorString = convertRGBToHex((short) (argb[1] & 0xFF), (short) (argb[2] & 0xFF), (short) (argb[3] & 0xFF)); + // TODO: 2021/4/26 添加透明度 +// if (xssfColor.hasTint()) { +// fillColorString += " * " + xssfColor.getTint(); +// byte[] rgb = xssfColor.getRGBWithTint(); +// fillColorString += " = [" + (argb[0] & 0xFF) + ", " + (rgb[0] & 0xFF) + ", " + (rgb[1] & 0xFF) + ", " + (rgb[2] & 0xFF) + "]"; +// } + } else if (color instanceof HSSFColor) { + HSSFColor hssfColor = (HSSFColor) color; + short[] rgb = hssfColor.getTriplet(); + fillColorString = convertRGBToHex((short) (rgb[0] & 0xFF), (short) (rgb[1] & 0xFF), (short) (rgb[2] & 0xFF)); + //去除黑色背景 + if (StringUtils.equals("#000000", fillColorString)) { + return null; + } + } + } + return fillColorString; + } + +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ConstantUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ConstantUtil.java new file mode 100644 index 00000000..29df40c5 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/ConstantUtil.java @@ -0,0 +1,313 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + + +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 来自:https://github.com/mengshukeji/LuckysheetServer + * + * @author cr + */ +public class ConstantUtil { + /** + * 导出。字体转换 + */ + public static Map ff_IntegerToName = new HashMap(); + /** + * 导入。字体转换 + */ + public static Map ff_NameToInteger = new HashMap(); + + /** + * 导入 36种数字格式。注意官方文档的编号不是连续的,22后面直接是37,所以数组中间补14个空值 + */ + public static String[] number_type = null; + /** + * 导入 36种格式的定义字符串 + */ + public static String[] number_format = null; + /** + * 数据类型 + */ + public static Map number_format_map = new HashMap(); + + static { + //格式 + nf(); + //字体 + ff(); + } + + private static void nf() { + number_type = new String[]{ + "General", "Decimal", "Decimal", "Decimal", "Decimal", "Currency", "Currency", "Currency", "Currency", + "Percentage", "Percentage", "Scientific", "Fraction", "Fraction", "Date", "Date", "Date", "Date", + "Time", "Time", "Time", "Time", "Time", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "Accounting", "Accounting", "Accounting", "Accounting", "Accounting", + "Currency", "Accounting", "Currency", "Time", "Time", "Time", "Scientific", "Text" + }; + + number_format = new String[]{ + "General", "0", "0.00", "#,##0", "#,##0.00", "$#,##0;($#,##0)", "$#,##0;[Red]($#,##0)", "$#,##0.00;($#,##0.00)", "$#,##0.00;[Red]($#,##0.00)", + "0%", "0.00%", "0.00E+00", "# ?/?", "# ??/??", "m/d/yyyy", "d-mmm-yy", "d-mmm", "mmm-yy", + "h:mm AM/PM", "h:mm:ss AM/PM", "h:mm", "h:mm:ss", "m/d/yyyy h:mm", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "#,##0;(#,##0)", "#,##0;[Red](#,##0)", "#,##0.00;(#,##0.00)", "#,##0.00;[Red](#,##0.00)", "_ * #,##0_ ;_ * (#,##0)_ ;_ * \"-\"_ ;_ @_", + "_ $* #,##0_ ;_ $* (#,##0)_ ;_ $* \"-\"_ ;_ @_", "_ * #,##0.00_ ;_ * (#,##0.00)_ ;_ * \"-\"??_ ;_ @_", "_ $* #,##0.00_ ;_ $* (#,##0.00)_ ;_ $* \"-\"??_ ;_ @_", "mm:ss", "[h]:mm:ss", "mm:ss.0", "##0.0E+00", "@" + }; + for (int x = 0; x < number_format.length; x++) { + if (number_format[x].length() > 0) { + number_format_map.put(number_format[x].toLowerCase(), x); + } + } + } + + private static void ff() { + //0 微软雅黑、1 宋体(Song)、2 黑体(ST Heiti)、3 楷体(ST Kaiti)、 4仿宋(ST FangSong)、 5 新宋体(ST Song)、 + // 6 华文新魏、 7华文行楷、 8 华文隶书、 9 Arial、 10 Times New Roman 、11 Tahoma 、12 Verdana + ff_IntegerToName.put(0, "微软雅黑"); + ff_IntegerToName.put(1, "宋体"); + ff_IntegerToName.put(2, "黑体"); + ff_IntegerToName.put(3, "楷体"); + ff_IntegerToName.put(4, "仿宋"); + ff_IntegerToName.put(5, "新宋体"); + ff_IntegerToName.put(6, "华文新魏"); + ff_IntegerToName.put(7, "华文行楷"); + ff_IntegerToName.put(8, "华文隶书"); + ff_IntegerToName.put(9, "Arial"); + ff_IntegerToName.put(10, "Times New Roman"); + ff_IntegerToName.put(11, "Tahoma"); + ff_IntegerToName.put(12, "Verdana"); + + //0 微软雅黑、1 宋体(Song)、2 黑体(ST Heiti)、3 楷体(ST Kaiti)、 4仿宋(ST FangSong)、 5 新宋体(ST Song)、 + // 6 华文新魏、 7华文行楷、 8 华文隶书、 9 Arial、 10 Times New Roman 、11 Tahoma 、12 Verdana + ff_NameToInteger.put("微软雅黑", 0); + ff_NameToInteger.put("宋体", 1); + ff_NameToInteger.put("Song", 1); + ff_NameToInteger.put("黑体", 2); + ff_NameToInteger.put("ST Heiti", 2); + ff_NameToInteger.put("楷体", 3); + ff_NameToInteger.put("ST Kaiti", 3); + ff_NameToInteger.put("仿宋", 4); + ff_NameToInteger.put("ST FangSong", 4); + ff_NameToInteger.put("新宋体", 5); + ff_NameToInteger.put("ST Song", 5); + ff_NameToInteger.put("华文新魏", 6); + ff_NameToInteger.put("华文行楷", 7); + ff_NameToInteger.put("华文隶书", 8); + ff_NameToInteger.put("Arial", 9); + ff_NameToInteger.put("Times New Roman", 10); + ff_NameToInteger.put("Tahoma", 11); + ff_NameToInteger.put("Verdana", 12); + } + + private static void borderType() { + //"border-left" | "border-right" | "border-top" | "border-bottom" | "border-all" + // | "border-outside" | "border-inside" | "border-horizontal" | "border-vertical" | "border-none" + ff_IntegerToName.put(0, "微软雅黑"); + ff_IntegerToName.put(1, "宋体"); + ff_IntegerToName.put(2, "黑体"); + ff_IntegerToName.put(3, "楷体"); + ff_IntegerToName.put(4, "仿宋"); + ff_IntegerToName.put(5, "新宋体"); + ff_IntegerToName.put(6, "华文新魏"); + ff_IntegerToName.put(7, "华文行楷"); + ff_IntegerToName.put(8, "华文隶书"); + ff_IntegerToName.put(9, "Arial"); + ff_IntegerToName.put(10, "Times New Roman"); + ff_IntegerToName.put(11, "Tahoma"); + ff_IntegerToName.put(12, "Verdana"); + + //0 微软雅黑、1 宋体(Song)、2 黑体(ST Heiti)、3 楷体(ST Kaiti)、 4仿宋(ST FangSong)、 5 新宋体(ST Song)、 + // 6 华文新魏、 7华文行楷、 8 华文隶书、 9 Arial、 10 Times New Roman 、11 Tahoma 、12 Verdana + ff_NameToInteger.put("微软雅黑", 0); + ff_NameToInteger.put("宋体", 1); + ff_NameToInteger.put("Song", 1); + ff_NameToInteger.put("黑体", 2); + ff_NameToInteger.put("ST Heiti", 2); + ff_NameToInteger.put("楷体", 3); + ff_NameToInteger.put("ST Kaiti", 3); + ff_NameToInteger.put("仿宋", 4); + ff_NameToInteger.put("ST FangSong", 4); + ff_NameToInteger.put("新宋体", 5); + ff_NameToInteger.put("ST Song", 5); + ff_NameToInteger.put("华文新魏", 6); + ff_NameToInteger.put("华文行楷", 7); + ff_NameToInteger.put("华文隶书", 8); + ff_NameToInteger.put("Arial", 9); + ff_NameToInteger.put("Times New Roman", 10); + ff_NameToInteger.put("Tahoma", 11); + ff_NameToInteger.put("Verdana", 12); + } + + + /** + * 按自定义格式 + * + * @param fa + * @return + */ + public static Integer getNumberFormatMap(String fa) { + if (number_format_map.containsKey(fa.toLowerCase())) { + return number_format_map.get(fa.toLowerCase()); + } + return -1; + } + + /** + * 获取poi表格垂直对齐 0 中间、1 上、2下 + * + * @param i + * @return + */ + public static VerticalAlignment getVerticalType(int i) { + if (0 == i) { + return VerticalAlignment.CENTER; + } else if (1 == i) { + return VerticalAlignment.TOP; + } else if (2 == i) { + return VerticalAlignment.BOTTOM; + } + //默认居中 + return VerticalAlignment.CENTER; + } + + /** + * 获取poi表格水平对齐 0 居中、1 左、2右 + * + * @param i + * @return + */ + public static HorizontalAlignment getHorizontaltype(int i) { + if (2 == i) { + return HorizontalAlignment.RIGHT; + } else if (1 == i) { + return HorizontalAlignment.LEFT; + } else if (0 == i) { + return HorizontalAlignment.CENTER; + } + //默认右 + return HorizontalAlignment.RIGHT; + } + + /** + * 文字旋转 + * 文字旋转角度(0=0,1=45,2=-45,3=竖排文字,4=90,5=-90) + * + * @param i + * @return + */ + public static short getRotation(int i) { + short t = 0; + switch (i) { + case 1: + t = 45; + break; + case 2: + t = -45; + break; + case 3: + t = 255; + break; + case 4: + t = 90; + break; + case 5: + t = -90; + break; + + default: + t = 0; + } + return t; + } + + + private static SimpleDateFormat df_DateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static Date stringToDateTime(String date) { + if (date == null || date.length() == 0) { + return null; + } + try { + return df_DateTime.parse(date); + } catch (ParseException e) { + return null; + } + } + + private static SimpleDateFormat df_Date = new SimpleDateFormat("yyyy-MM-dd"); + + public static Date stringToDate(String date) { + if (date == null || date.length() == 0) { + return null; + } + try { + return df_Date.parse(date); + } catch (ParseException e) { + return null; + } + } + + public static Date toDate(String numberString) { + try { + Double _d = Double.parseDouble(numberString); + String _s = toDate(_d, "yyyy-MM-dd HH:mm:ss"); + if (numberString.indexOf(".") > -1) { + return stringToDate(_s); + } else { + return stringToDateTime(_s); + } + + } catch (Exception ex) { + System.out.println(ex.toString() + " " + numberString); + } + return null; + } + + private static final int SECONDS_PER_MINUTE = 60; + private static final int MINUTES_PER_HOUR = 60; + private static final int HOURS_PER_DAY = 24; + private static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE); + /** + * 一天的毫秒数 + **/ + private static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L; + + /** + * 转换方法 + * + * @parma numberString 要转换的浮点数 + * @parma format 要获得的格式 例如"hh:mm:ss" + **/ + public static String toDate(double numberString, String format) { + SimpleDateFormat sdFormat = new SimpleDateFormat(format); + int wholeDays = (int) Math.floor(numberString); + int millisecondsInday = (int) ((numberString - wholeDays) * DAY_MILLISECONDS + 0.5); + Calendar calendar = new GregorianCalendar(); + setCalendar(calendar, wholeDays, millisecondsInday, false); + return sdFormat.format(calendar.getTime()); + } + + private static void setCalendar(Calendar calendar, int wholeDays, + int millisecondsInDay, boolean use1904windowing) { + int startYear = 1900; + int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't + if (use1904windowing) { + startYear = 1904; + dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day + } else if (wholeDays < 61) { + // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists + // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation + dayAdjust = 0; + } + calendar.set(startYear, 0, wholeDays + dayAdjust, 0, 0, 0); + calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay); + } +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/MSExcelUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/MSExcelUtil.java new file mode 100644 index 00000000..1e1d167e --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/MSExcelUtil.java @@ -0,0 +1,28 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + +public class MSExcelUtil { + public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256; + public static final short EXCEL_ROW_HEIGHT_FACTOR = 20; + public static final int UNIT_OFFSET_LENGTH = 7; + public static final int[] UNIT_OFFSET_MAP = new int[]{0, 36, 73, 109, 146, 182, 219}; + + public static short pixel2WidthUnits(int pxs) { + short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH)); + widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)]; + return widthUnits; + } + + public static int widthUnits2Pixel(short widthUnits) { + int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) * UNIT_OFFSET_LENGTH; + int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR; + pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH)); + return pixels; + } + + public static int heightUnits2Pixel(short heightUnits) { + int pixels = (heightUnits / EXCEL_ROW_HEIGHT_FACTOR); + int offsetWidthUnits = heightUnits % EXCEL_ROW_HEIGHT_FACTOR; + pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_ROW_HEIGHT_FACTOR / UNIT_OFFSET_LENGTH)); + return pixels; + } +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java new file mode 100644 index 00000000..0f30339d --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java @@ -0,0 +1,860 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.util.*; + +/** + * 来自:https://github.com/mengshukeji/LuckysheetServer + * sheet操作 + * + * @author Administrator + */ +@Slf4j +public class XlsSheetUtil { + /** + * 导出sheet + * + * @param wb + * @param sheetNum + * @param dbObject + */ + public static void exportSheet(Workbook wb, int sheetNum, JSONObject dbObject) { + Sheet sheet = wb.createSheet(); + + //设置sheet位置,名称 + if (dbObject.containsKey("name") && dbObject.get("name") != null) { + wb.setSheetName(sheetNum, dbObject.get("name").toString()); + } else { + wb.setSheetName(sheetNum, "sheet" + sheetNum); + } + //是否隐藏 + if (dbObject.containsKey("hide") && dbObject.get("hide").toString().equals("1")) { + wb.setSheetHidden(sheetNum, true); + } + //是否当前选中页 + if (dbObject.containsKey("status") && dbObject.get("status").toString().equals("1")) { + sheet.setSelected(true); + } + + + //循环数据 + if (dbObject.containsKey("celldata") && dbObject.get("celldata") != null) { + //取到所有单元格集合 + List cells_json = (List) dbObject.get("celldata"); + Map> cellMap = cellGroup(cells_json); + //循环每一行 + for (Integer r : cellMap.keySet()) { + Row row = sheet.createRow(r); + //循环每一列 + for (JSONObject col : cellMap.get(r)) { + createCell(wb, sheet, row, col); + } + } + } + + if (dbObject.containsKey("config") && dbObject.getJSONObject("config").containsKey("borderInfo")) { + JSONArray borderInfo = dbObject.getJSONObject("config").getJSONArray("borderInfo"); + setCellBoard(wb, borderInfo, sheet); + } + + + setColumAndRow(dbObject, sheet); + + } + + /** + * 每一个单元格 + * + * @param row + * @param dbObject + */ + private static void createCell(Workbook wb, Sheet sheet, Row row, JSONObject dbObject) { + if (dbObject.containsKey("c")) { + Integer c = getStrToInt(dbObject.get("c")); + if (c != null) { + Cell cell = row.createCell(c); + //取单元格中的v_json + if (dbObject.containsKey("v")) { + //获取v对象 + Object obj = dbObject.get("v"); + if (obj == null) { + //没有内容 + return; + } + //如果v对象直接是字符串 + if (obj instanceof String) { + if (((String) obj).length() > 0) { + cell.setCellValue(obj.toString()); + } + return; + } + + //转换v为对象(v是一个对象) + JSONObject v_json = (JSONObject) obj; + //样式 + CellStyle style = wb.createCellStyle(); + cell.setCellStyle(style); + + + //合并单元格 + //参数1:起始行 参数2:终止行 参数3:起始列 参数4:终止列 + //CellRangeAddress region1 = new CellRangeAddress(rowNumber, rowNumber, (short) 0, (short) 11); + + //mc 合并单元格 + if (v_json.containsKey("mc")) { + //是合并的单元格 + JSONObject mc = v_json.getJSONObject("mc"); + if (mc.containsKey("rs") && mc.containsKey("cs")) { + //合并的第一个单元格 + if (mc.containsKey("r") && mc.containsKey("c")) { + Integer _rs = getIntByDBObject(mc, "rs") - 1; + Integer _cs = getIntByDBObject(mc, "cs") - 1; + Integer _r = getIntByDBObject(mc, "r"); + Integer _c = getIntByDBObject(mc, "c"); + + CellRangeAddress region = new CellRangeAddress(_r.shortValue(), (_r.shortValue() + _rs.shortValue()), _c.shortValue(), (_c.shortValue() + _cs.shortValue())); + sheet.addMergedRegion(region); + } + } else { + //不是合并的第一个单元格 + return; + } + } + + + //取v值 (在数据类型中处理) + //ct 单元格值格式 (fa,t) + setFormatByCt(wb, cell, style, v_json); + + //font设置 + setCellStyleFont(wb, style, v_json); + + //bg 背景颜色 + if (v_json.containsKey("bg")) { + String _v = getByDBObject(v_json, "bg"); + Short _color = ColorUtil.getColorByStr(_v); + if (_color != null) { + style.setFillForegroundColor(_color); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + } + } + + //vt 垂直对齐 垂直对齐方式(0=居中,1=上,2=下) + if (v_json.containsKey("vt")) { + Integer _v = getIntByDBObject(v_json, "vt"); + if (_v != null && _v >= 0 && _v <= 2) { + style.setVerticalAlignment(ConstantUtil.getVerticalType(_v)); + } + } else { + //默认设置居中 + style.setVerticalAlignment(ConstantUtil.getVerticalType(0)); + } + + //ht 水平对齐 水平对齐方式(0=居中,1=左对齐,2=右对齐) + if (v_json.containsKey("ht")) { + Integer _v = getIntByDBObject(v_json, "ht"); + if (_v != null && _v >= 0 && _v <= 2) { + style.setAlignment(ConstantUtil.getHorizontaltype(_v)); + } + } else { + //默认设置左对齐 + style.setAlignment(ConstantUtil.getHorizontaltype(1)); + } + + //tr 文字旋转 文字旋转角度(0=0,1=45,2=-45,3=竖排文字,4=90,5=-90) + if (v_json.containsKey("tr")) { + Integer _v = getIntByDBObject(v_json, "tr"); + if (_v != null) { + style.setRotation(ConstantUtil.getRotation(_v)); + } + } + + //tb 文本换行 0 截断、1溢出、2 自动换行 + // 2:setTextWrapped 0和1:IsTextWrapped = true + if (v_json.containsKey("tb")) { + Integer _v = getIntByDBObject(v_json, "tb"); + if (_v != null) { + if (_v >= 0 && _v <= 1) { + style.setWrapText(false); + } else { + style.setWrapText(true); + } + } + } + + //f 公式 + if (v_json.containsKey("f")) { + String _v = getByDBObject(v_json, "f"); + if (_v.length() > 0) { + try { + if (_v.startsWith("=")) { + cell.setCellFormula(_v.substring(1)); + } else { + cell.setCellFormula(_v); + } + } catch (Exception ex) { + log.error("公式 {};Error:{}", _v, ex.toString()); + } + } + } + + + } + + } + } + } + + /** + * 设置边框 + * + * @param borderInfo + * @param sheet + */ + private static void setCellBoard(Workbook wb, JSONArray borderInfo, Sheet sheet) { + + + //一定要通过 cell.getCellStyle() 不然的话之前设置的样式会丢失 + //设置边框 + for (int i = 0; i < borderInfo.size(); i++) { + JSONObject borderInfoObject = (JSONObject) borderInfo.get(i); + if (borderInfoObject.get("rangeType").equals("cell")) {//单个单元格 + JSONObject borderValueObject = borderInfoObject.getJSONObject("value"); + + JSONObject l = borderValueObject.getJSONObject("l"); + JSONObject r = borderValueObject.getJSONObject("r"); + JSONObject t = borderValueObject.getJSONObject("t"); + JSONObject b = borderValueObject.getJSONObject("b"); + + + int row_ = borderValueObject.getInteger("row_index"); + int col_ = borderValueObject.getInteger("col_index"); + + Row row = sheet.getRow(row_); + if (null == row) { + row = sheet.createRow(row_); + } + Cell cell = row.getCell(col_); + CellStyle style; + if (null == cell) { + style = wb.createCellStyle(); + cell = row.createCell(col_); + cell.setCellStyle(style); + } else { + style = cell.getCellStyle(); + } + + + if (l != null) { + style.setBorderLeft(BorderStyle.valueOf(l.getShort("style"))); //左边框 + Short color = ColorUtil.getColorByStr(l.getString("color")); + if (null != color) { + style.setLeftBorderColor(color);//左边框颜色 + } + + } + if (r != null) { + style.setBorderRight(BorderStyle.valueOf(r.getShort("style"))); //右边框 + Short color = ColorUtil.getColorByStr(r.getString("color")); + if (null != color) { + style.setRightBorderColor(color);//右边框颜色 + } + + } + if (t != null) { + style.setBorderTop(BorderStyle.valueOf(t.getShort("style"))); //顶部边框 + Short _vcolor = ColorUtil.getColorByStr(t.getString("color")); + if (null != _vcolor) { + style.setTopBorderColor(_vcolor);//顶部边框颜色 + } + + } + if (b != null) { + style.setBorderBottom(BorderStyle.valueOf(b.getShort("style"))); //底部边框 + Short _vcolor = ColorUtil.getColorByStr(b.getString("color")); + if (_vcolor != null) { + //底部边框颜色 + style.setBottomBorderColor(_vcolor); + } + } + + } else if (borderInfoObject.get("rangeType").equals("range")) { + //选区 + Short style_ = borderInfoObject.getShort("style"); + String borderType = borderInfoObject.getString("borderType"); + Short color = ColorUtil.getColorByStr(borderInfoObject.getString("color")); + JSONObject rangObject = (JSONObject) ((JSONArray) (borderInfoObject.get("range"))).get(0); + + JSONArray rowList = rangObject.getJSONArray("row"); + JSONArray columnList = rangObject.getJSONArray("column"); + + + for (int row_ = rowList.getInteger(0); row_ < rowList.getInteger(rowList.size() - 1) + 1; row_++) { + for (int col_ = columnList.getInteger(0); col_ < columnList.getInteger(columnList.size() - 1) + 1; col_++) { + Row row = sheet.getRow(row_); + if (null == row) { + row = sheet.createRow(row_); + } + Cell cell = row.getCell(col_); + CellStyle style; + if (null == cell) { + style = wb.createCellStyle(); + cell = row.createCell(col_); + cell.setCellStyle(style); + } else { + style = cell.getCellStyle(); + } + + //"border-left" | "border-right" | "border-top" | "border-bottom" | "border-all" | "border-horizontal" | "border-vertical" + // "border-outside" | "border-inside" | | "border-none" + if ("border-left".equals(borderType) || "border-all".equals(borderType)) { + style.setBorderLeft(BorderStyle.valueOf(style_)); //左边框 + style.setLeftBorderColor(color);//左边框颜色 + } + if ("border-right".equals(borderType) || "border-all".equals(borderType)) { + style.setBorderRight(BorderStyle.valueOf(style_)); //右边框 + style.setRightBorderColor(color);//右边框颜色 + } + + if ("border-top".equals(borderType) || "border-all".equals(borderType)) { + style.setBorderTop(BorderStyle.valueOf(style_)); //顶部边框 + style.setTopBorderColor(color);//顶部边框颜色 + } + + if ("border-bottom".equals(borderType) || "border-all".equals(borderType)) { + style.setBorderBottom(BorderStyle.valueOf(style_)); //底部边框 + style.setBottomBorderColor(color);//底部边框颜色 } + } + + if ("border-outside".equals(borderType)) { + //外圈边框 + if (row_ == rowList.getInteger(0)) { + style.setBorderTop(BorderStyle.valueOf(style_)); //顶部边框 + style.setTopBorderColor(color);//顶部边框颜色 + } + if (col_ == columnList.getInteger(0)) { + style.setBorderLeft(BorderStyle.valueOf(style_)); //左边框 + style.setLeftBorderColor(color);//左边框颜色 + } + if (row_ == rowList.getInteger(rowList.size() - 1)) { + style.setBorderBottom(BorderStyle.valueOf(style_)); //底部边框 + style.setBottomBorderColor(color);//底部边框颜色 } + } + if (col_ == columnList.getInteger(columnList.size() - 1)) { + style.setBorderRight(BorderStyle.valueOf(style_)); //右边框 + style.setRightBorderColor(color);//右边框颜色 + } + + } + + if ("border-horizontal".equals(borderType) || "border-inside".equals(borderType)) { + //内部横线 + if (row_ >= rowList.getInteger(0) + && row_ < rowList.getInteger(rowList.size() - 1) + && col_ >= columnList.getInteger(0) + && col_ <= columnList.getInteger(columnList.size() - 1)) { + style.setBorderBottom(BorderStyle.valueOf(style_)); //底部边框 + style.setBottomBorderColor(color);//底部边框颜色 } + } + } + + if ("border-vertical".equals(borderType) || "border-inside".equals(borderType)) { + //内部竖线 + if (row_ >= rowList.getInteger(0) + && row_ <= rowList.getInteger(rowList.size() - 1) + && col_ >= columnList.getInteger(0) + && col_ < columnList.getInteger(columnList.size() - 1)) { + style.setBorderRight(BorderStyle.valueOf(style_)); //右边框 + style.setRightBorderColor(color);//右边框颜色 + } + } + + if ("border-none".equals(borderType)) { + style.setBorderLeft(BorderStyle.NONE); //左边框 + style.setBorderRight(BorderStyle.NONE); //左边框 + style.setBorderTop(BorderStyle.NONE); //左边框 + style.setBorderBottom(BorderStyle.NONE); //左边框 + } + + } + } + + + } + } + + } + + + /** + * 设置单元格,宽、高 + * + * @param dbObject + * @param sheet + */ + private static void setColumAndRow(JSONObject dbObject, Sheet sheet) { + if (dbObject.containsKey("config")) { + JSONObject config = dbObject.getJSONObject("config"); + + if (config.containsKey("columnlen")) { + JSONObject columnlen = config.getJSONObject("columnlen"); + if (columnlen != null) { + for (String k : columnlen.keySet()) { + Integer _i = getStrToInt(k); + Integer _v = getStrToInt(columnlen.get(k).toString()); + if (_i != null && _v != null) { +// sheet.setColumnWidth(_i, MSExcelUtil.heightUnits2Pixel(_v.shortValue())); + // TODO 乘以32,有待商榷 + sheet.setColumnWidth(_i, _v * 32); + } + } + } + } + if (config.containsKey("rowlen")) { + JSONObject rowlen = config.getJSONObject("rowlen"); + if (rowlen != null) { + for (String k : rowlen.keySet()) { + Integer _i = getStrToInt(k); + Integer _v = getStrToInt(rowlen.get(k).toString()); + if (_i != null && _v != null) { + Row row = sheet.getRow(_i); + if (row != null) { +// row.setHeightInPoints(MSExcelUtil.pixel2WidthUnits(_v.shortValue())); + row.setHeightInPoints(_v.shortValue()); + } + } + } + } + } + } + } + + /** + * 单元格字体相关样式 + * + * @param wb + * @param style + * @param dbObject + */ + private static void setCellStyleFont(Workbook wb, CellStyle style, JSONObject dbObject) { + Font font = wb.createFont(); + style.setFont(font); + + //ff 字体 + if (dbObject.containsKey("ff")) { + if (dbObject.get("ff") instanceof Integer) { + Integer _v = getIntByDBObject(dbObject, "ff"); + if (_v != null && ConstantUtil.ff_IntegerToName.containsKey(_v)) { + font.setFontName(ConstantUtil.ff_IntegerToName.get(_v)); + } + } else if (dbObject.get("ff") instanceof String) { + font.setFontName(getByDBObject(dbObject, "ff")); + } + } + //fc 字体颜色 + if (dbObject.containsKey("fc")) { + String _v = getByDBObject(dbObject, "fc"); + Short _color = ColorUtil.getColorByStr(_v); + if (_color != null) { + font.setColor(_color); + } + } + //bl 粗体 + if (dbObject.containsKey("bl")) { + Integer _v = getIntByDBObject(dbObject, "bl"); + if (_v != null) { + if (_v.equals(1)) { + //是否粗体显示 + font.setBold(true); + } else { + font.setBold(false); + } + } + } + //it 斜体 + if (dbObject.containsKey("it")) { + Integer _v = getIntByDBObject(dbObject, "it"); + if (_v != null) { + if (_v.equals(1)) { + font.setItalic(true); + } else { + font.setItalic(false); + } + } + } + //fs 字体大小 + if (dbObject.containsKey("fs")) { + Integer _v = getStrToInt(getObjectByDBObject(dbObject, "fs")); + if (_v != null) { + font.setFontHeightInPoints(_v.shortValue()); + } + } + //cl 删除线 (导入没有) 0 常规 、 1 删除线 + if (dbObject.containsKey("cl")) { + Integer _v = getIntByDBObject(dbObject, "cl"); + if (_v != null) { + if (_v.equals(1)) { + font.setStrikeout(true); + } + } + } + //ul 下划线 + if (dbObject.containsKey("ul")) { + Integer _v = getIntByDBObject(dbObject, "ul"); + if (_v != null) { + if (_v.equals(1)) { + font.setUnderline(Font.U_SINGLE); + } else { + font.setUnderline(Font.U_NONE); + } + } + } + + } + + /** + * 设置cell边框颜色样式 + * + * @param style 样式 + * @param dbObject json对象 + * @param bs 样式 + * @param bc 样式 + */ + private static void setBorderStyle(CellStyle style, JSONObject dbObject, String bs, String bc) { + //bs 边框样式 + if (dbObject.containsKey(bs)) { + Integer _v = getStrToInt(getByDBObject(dbObject, bs)); + if (_v != null) { + //边框没有,不作改变 + if (bs.equals("bs") || bs.equals("bs_t")) { + style.setBorderTop(BorderStyle.valueOf(_v.shortValue())); + } + if (bs.equals("bs") || bs.equals("bs_b")) { + style.setBorderBottom(BorderStyle.valueOf(_v.shortValue())); + } + if (bs.equals("bs") || bs.equals("bs_l")) { + style.setBorderLeft(BorderStyle.valueOf(_v.shortValue())); + } + if (bs.equals("bs") || bs.equals("bs_r")) { + style.setBorderRight(BorderStyle.valueOf(_v.shortValue())); + } + + //bc 边框颜色 + String _vcolor = getByDBObject(dbObject, bc); + if (_vcolor != null) { + Short _color = ColorUtil.getColorByStr(_vcolor); + if (_color != null) { + if (bc.equals("bc") || bc.equals("bc_t")) { + style.setTopBorderColor(_color); + } + if (bc.equals("bc") || bc.equals("bc_b")) { + style.setBottomBorderColor(_color); + } + if (bc.equals("bc") || bc.equals("bc_l")) { + style.setLeftBorderColor(_color); + } + if (bc.equals("bc") || bc.equals("bc_r")) { + style.setRightBorderColor(_color); + } + } + } + } + } + } + + + /** + * 设置单元格格式 ct 单元格值格式 (fa,t) + * + * @param cell + * @param style + * @param dbObject + */ + private static void setFormatByCt(Workbook wb, Cell cell, CellStyle style, JSONObject dbObject) { + + if (!dbObject.containsKey("v") && dbObject.containsKey("ct")) { + /* 处理以下数据结构 + { + "celldata": [{ + "c": 0, + "r": 8, + "v": { + "ct": { + "s": [{ + "v": "sdsdgdf\r\ndfgdfg\r\ndsfgdfgdf\r\ndsfgdfg" + }], + "t": "inlineStr", + "fa": "General" + } + } + }] + } + */ + JSONObject ct = dbObject.getJSONObject("ct"); + if (ct.containsKey("s")) { + Object s = ct.get("s"); + if (s instanceof List && ((List) s).size() > 0) { + JSONObject _s1 = (JSONObject) ((List) s).get(0); + if (_s1.containsKey("v") && _s1.get("v") instanceof String) { + dbObject.put("v", _s1.get("v")); + style.setWrapText(true); + } + } + + } + } + + //String v = ""; //初始化 + if (dbObject.containsKey("v")) { + //v = v_json.get("v").toString(); + //取到v后,存到poi单元格对象 + //设置该单元格值 + //cell.setValue(v); + + //String v=getByDBObject(v_json,"v"); + //cell.setValue(v); + Object obj = getObjectByDBObject(dbObject, "v"); + if (obj instanceof Number) { + cell.setCellValue(Double.valueOf(obj.toString())); + } else if (obj instanceof Double) { + cell.setCellValue((Double) obj); + } else if (obj instanceof Date) { + cell.setCellValue((Date) obj); + } else if (obj instanceof Calendar) { + cell.setCellValue((Calendar) obj); + } else if (obj instanceof RichTextString) { + cell.setCellValue((RichTextString) obj); + } else if (obj instanceof String) { + cell.setCellValue((String) obj); + } else { + cell.setCellValue(obj.toString()); + } + + } + + if (dbObject.containsKey("ct")) { + JSONObject ct = dbObject.getJSONObject("ct"); + if (ct.containsKey("fa") && ct.containsKey("t")) { + //t 0=bool,1=datetime,2=error,3=null,4=numeric,5=string,6=unknown + String fa = getByDBObject(ct, "fa"); //单元格格式format定义串 + String t = getByDBObject(ct, "t"); //单元格格式type类型 + + Integer _i = ConstantUtil.getNumberFormatMap(fa); + switch (t) { + case "s": { + //字符串 + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + style.setDataFormat((short) 0); + } + cell.setCellType(CellType.STRING); + break; + } + case "d": { + //日期 + Date _d = null; + String v = getByDBObject(dbObject, "m"); + if (v.length() == 0) { + v = getByDBObject(dbObject, "v"); + } + if (v.length() > 0) { + if (v.indexOf("-") > -1) { + if (v.indexOf(":") > -1) { + _d = ConstantUtil.stringToDateTime(v); + } else { + _d = ConstantUtil.stringToDate(v); + } + } else { + _d = ConstantUtil.toDate(v); + } + } + if (_d != null) { + //能转换为日期 + cell.setCellValue(_d); + DataFormat format = wb.createDataFormat(); + style.setDataFormat(format.getFormat(fa)); + + } else { + //不能转换为日期 + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + style.setDataFormat((short) 0); + } + } + break; + } + case "b": { + //逻辑 + cell.setCellType(CellType.BOOLEAN); + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + DataFormat format = wb.createDataFormat(); + style.setDataFormat(format.getFormat(fa)); + } + break; + } + case "n": { + //数值 +// cell.setCellType(CellType.NUMERIC); + //数字转字符串 + cell.setCellType(CellType.STRING); + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + DataFormat format = wb.createDataFormat(); + style.setDataFormat(format.getFormat(fa)); + } + break; + } + case "u": + case "g": { + //general 自动类型 + //cell.setCellType(CellType._NONE); + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + DataFormat format = wb.createDataFormat(); + style.setDataFormat(format.getFormat(fa)); + } + break; + } + case "e": { + //错误 + cell.setCellType(CellType.ERROR); + if (_i >= 0) { + style.setDataFormat(_i.shortValue()); + } else { + DataFormat format = wb.createDataFormat(); + style.setDataFormat(format.getFormat(fa)); + } + break; + } + + } + + } + + } + } + + /** + * 内容按行分组 + * + * @param cells + * @return + */ + private static Map> cellGroup(List cells) { + Map> cellMap = new HashMap<>(100); + for (JSONObject dbObject : cells) { + //行号 + if (dbObject.containsKey("r")) { + Integer r = getStrToInt(dbObject.get("r")); + if (r != null) { + if (cellMap.containsKey(r)) { + cellMap.get(r).add(dbObject); + } else { + List list = new ArrayList<>(10); + list.add(dbObject); + cellMap.put(r, list); + } + } + } + + } + return cellMap; + } + + + /** + * 获取一个k的值 + * + * @param b + * @param k + * @return + */ + public static String getByDBObject(JSONObject b, String k) { + if (b.containsKey(k)) { + if (b.get(k) != null && b.get(k) instanceof String) { + return b.getString(k); + } + } + return null; + } + + /** + * 获取一个k的值 + * + * @param b + * @param k + * @return + */ + public static Object getObjectByDBObject(JSONObject b, String k) { + if (b.containsKey(k)) { + if (b.get(k) != null) { + return b.get(k); + } + } + return ""; + } + + /** + * 没有/无法转换 返回null + * + * @param b + * @param k + * @return + */ + public static Integer getIntByDBObject(JSONObject b, String k) { + if (b.containsKey(k)) { + if (b.get(k) != null) { + try { + String _s = b.getString(k).replace("px", ""); + Double _d = Double.parseDouble(_s); + return _d.intValue(); + } catch (Exception ex) { + log.error(ex.getMessage()); + return null; + } + } + } + return null; + } + + /** + * 转int + * + * @param str + * @return + */ + private static Integer getStrToInt(Object str) { + try { + if (str != null) { + return Integer.parseInt(str.toString()); + } + return null; + } catch (Exception ex) { + log.error("String:{};Error:{}", str, ex.getMessage()); + return null; + } + } + + private static Short getStrToShort(Object str) { + try { + if (str != null) { + return Short.parseShort(str.toString()); + } + return null; + } catch (Exception ex) { + log.error("String:{};Error:{}", str, ex.getMessage()); + return null; + } + } +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsUtil.java new file mode 100644 index 00000000..51ea0d3e --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsUtil.java @@ -0,0 +1,453 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.anjiplus.template.gaea.business.enums.ExcelCenterStyleEnum; +import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.GridRecordDataModel; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFFont; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFColor; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.validation.constraints.NotNull; +import java.io.IOException; +import java.io.OutputStream; +import java.util.*; + +/** + * 来自:https://github.com/mengshukeji/LuckysheetServer + * 使用poi导出xls + * + * @author Administrator + */ +public class XlsUtil { + + private final static String MODEL = "{\"c\":0,\"r\":0,\"v\":{\"m\":\"模板\",\"v\":\"模板\",\"bl\":1,\"ct\":{\"t\":\"g\",\"fa\":\"General\"}}}"; + private final static String BORDER_MODEL = "{\"rangeType\":\"cell\",\"value\":{\"b\":{\"color\":\"rgb(0, 0, 0)\",\"style\":1},\"r\":{\"color\":\"rgb(0, 0, 0)\",\"style\":1},\"col_index\":5,\"t\":{\"color\":\"rgb(0, 0, 0)\",\"style\":1},\"row_index\":7,\"l\":{\"color\":\"rgb(0, 0, 0)\",\"style\":1}}}"; + /** + * 默认行数 + */ + private static final int DEFAULT_ROW_INDEX = 84; + /** + * 默认列数 + */ + private static final int DEFAULT_COLUMN_INDEX = 64; + + /** + * 输出文件流 + * + * @param outputStream 流 + * @param isXlsx 是否是xlsx + * @param dbObjectList 数据 + */ + public static void exportXlsFile(OutputStream outputStream, Boolean isXlsx, List dbObjectList) throws IOException { + Workbook wb = null; + if (isXlsx) { + wb = new XSSFWorkbook(); + } else { + wb = new HSSFWorkbook(); + } + if (dbObjectList != null && dbObjectList.size() > 0) { + for (int x = 0; x < dbObjectList.size(); x++) { + XlsSheetUtil.exportSheet(wb, x, dbObjectList.get(x)); + } + } + wb.write(outputStream); + } + + /** + * @param workbook 工作簿 + * @return Map + * @description 读取excel + * @author zhouhang + * @date 2021/4/20 + */ + public static List readExcel(Workbook workbook) { + List list = new ArrayList<>(); + Iterator sheetIterator = workbook.sheetIterator(); + int sheetIndex = 0; + while (sheetIterator.hasNext()) { + Sheet sheet = sheetIterator.next(); + //生成默认MODEL + GridRecordDataModel model; + if (Objects.equals(0, sheetIndex)) { + model = strToModel("", (sheetIndex + 1) + "", 1, sheetIndex); + } else { + model = strToModel("", (sheetIndex + 1) + "", 0, sheetIndex); + } + sheetIndex++; + //读取sheet页 + readSheet(sheet, model, workbook); + //设置sheet页名称 + model.getJson_data().put("name", sheet.getSheetName()); + list.add(model); + } + return list; + } + + public static GridRecordDataModel strToModel(String list_id, String index, int status, int order) { + String strSheet = "{\"row\":84,\"name\":\"reSheetName\",\"chart\":[],\"color\":\"\",\"index\":\"reIndex\",\"order\":reOrder,\"column\":60,\"config\":{},\"status\":reStatus,\"celldata\":[],\"ch_width\":4748,\"rowsplit\":[],\"rh_height\":1790,\"scrollTop\":0,\"scrollLeft\":0,\"visibledatarow\":[],\"visibledatacolumn\":[],\"jfgird_select_save\":[],\"jfgrid_selection_range\":{}}"; + strSheet = strSheet.replace("reSheetName", "Sheet" + index).replace("reIndex", index).replace("reOrder", order + "").replace("reStatus", status + ""); + + JSONObject bson = JSONObject.parseObject(strSheet); + GridRecordDataModel model = new GridRecordDataModel(); + model.setBlock_id("fblock"); + model.setRow_col("5_5"); + model.setIndex(index); + model.setIs_delete(0); + model.setJson_data(bson); + model.setStatus(status); + model.setOrder(order); + model.setList_id(list_id); + return model; + } + + /** + * @param sheet sheet页 + * @param model 数据存储 + * @param workbook excel + * @description 读取单个sheet页 + * @author zhouhang + * @date 2021/4/20 + */ + private static void readSheet(Sheet sheet, GridRecordDataModel model, Workbook workbook) { + //excel数据集合 + List dataList = new ArrayList<>(); + model.setDataList(dataList); + //获取行迭代器 + Iterator rowIterator = sheet.rowIterator(); + //获取合并单元格信息 + Map rangeMap = getRangeMap(sheet); + //记录最大列 + int maxCellNumber = 0; + int maxRowNumber = 0; + //列宽 + JSONObject columnLenObj = new JSONObject(); + //行高 + JSONObject rowLenObj = new JSONObject(); + //读取文档 + while (rowIterator.hasNext()) { + Row row = rowIterator.next(); + int rowLen = ((int) row.getHeight()) / 20; + if (rowLen == 0) { + rowLen = 30; + } + rowLenObj.put(row.getRowNum() + "", rowLen); + Iterator cellIterator = row.cellIterator(); + maxRowNumber = row.getRowNum(); + while (cellIterator.hasNext()) { + //"{\"c\":0,\"r\":0,\"v\":{\"m\":\"模板\",\"v\":\"模板\",\"bl\":1,\"ct\":{\"t\":\"g\",\"fa\":\"General\"}}}"; + JSONObject dataModel = JSONObject.parseObject(MODEL); + //初始化默认单元格内容 + Cell cell = cellIterator.next(); + int columnLen = sheet.getColumnWidth(cell.getColumnIndex()) / 25; + if (columnLen == 0) { + columnLen = 73; + } + columnLenObj.put(cell.getColumnIndex() + "", columnLen); + //修改最大列 + maxCellNumber = Math.max(cell.getColumnIndex(), maxCellNumber); + //设置行列 + dataModel.put("c", cell.getColumnIndex()); + dataModel.put("r", row.getRowNum()); + //获取单元格内容 + switch (cell.getCellType()) { + case STRING: + dataModel.getJSONObject("v").put("m", cell.getStringCellValue()); + dataModel.getJSONObject("v").put("v", cell.getStringCellValue()); + break; + case NUMERIC: + dataModel.getJSONObject("v").put("m", cell.getNumericCellValue()); + dataModel.getJSONObject("v").put("v", cell.getNumericCellValue()); + break; + case BLANK: + dataModel.getJSONObject("v").put("m", ""); + dataModel.getJSONObject("v").put("v", ""); + break; + case BOOLEAN: + dataModel.getJSONObject("v").put("m", cell.getBooleanCellValue()); + dataModel.getJSONObject("v").put("v", cell.getBooleanCellValue()); + break; + case ERROR: + dataModel.getJSONObject("v").put("m", cell.getErrorCellValue()); + dataModel.getJSONObject("v").put("v", cell.getErrorCellValue()); + break; + default: + dataModel.getJSONObject("v").put("m", ""); + dataModel.getJSONObject("v").put("v", ""); + } + //设置单元格合并标记 + dealWithCellMarge(rangeMap, row, cell, dataModel); + //设置单元格样式、合并单元格信息 + dealWithExcelStyle(model, dataModel, cell, sheet, workbook); + dataList.add(dataModel); + } + } + //设置最大行、列 + model.getJson_data().put("column", Math.max(maxCellNumber, DEFAULT_COLUMN_INDEX)); + model.getJson_data().put("row", Math.max(maxRowNumber, DEFAULT_ROW_INDEX)); + //设置行高、列宽 + model.getJson_data().getJSONObject("config").put("columnlen", columnLenObj); + model.getJson_data().getJSONObject("config").put("rowlen", rowLenObj); + } + + /** + * @param sheet sheet页信息 + * @return Map 单元格合并信息 + * @description 获取合并单元格信息 所有合并单元的MAP + * @author zhouhang + * @date 2021/4/21 + */ + @NotNull + private static Map getRangeMap(Sheet sheet) { + List rangeAddressList = sheet.getMergedRegions(); + Map rangeMap = new HashMap<>(rangeAddressList.size() * 5); + for (CellRangeAddress cellAddresses : rangeAddressList) { + for (int i = cellAddresses.getFirstRow(); i <= cellAddresses.getLastRow(); i++) { + for (int j = cellAddresses.getFirstColumn(); j <= cellAddresses.getLastColumn(); j++) { + if (i == cellAddresses.getFirstRow() && j == cellAddresses.getFirstColumn()) { + //单元格合并初始值特殊标记 + rangeMap.put(i + "_" + j, cellAddresses.getFirstRow() + "_" + cellAddresses.getFirstColumn() + "_" + cellAddresses.getLastRow() + "_" + cellAddresses.getLastColumn()); + } else { + rangeMap.put(i + "_" + j, cellAddresses.getFirstRow() + "_" + cellAddresses.getFirstColumn()); + } + } + } + } + return rangeMap; + } + + /** + * @param rangeMap 合并信息 + * @param row 行信息 + * @param cell 单元格 + * @param dataModel 单元格数据存储信息 + * @description 设置单元格合并标记 + * @author zhouhang + * @date 2021/4/21 + */ + private static void dealWithCellMarge(Map rangeMap, Row row, Cell cell, JSONObject dataModel) { + if (rangeMap.containsKey(row.getRowNum() + "_" + cell.getColumnIndex())) { + String margeValue = rangeMap.get(row.getRowNum() + "_" + cell.getColumnIndex()); + JSONObject mcData = new JSONObject(); + String[] s = margeValue.split("_"); + mcData.put("r", Integer.parseInt(s[0])); + mcData.put("c", Integer.parseInt(s[1])); + if (s.length == 4) { + mcData.put("rs", Integer.parseInt(s[2]) - Integer.parseInt(s[0]) + 1); + mcData.put("cs", Integer.parseInt(s[3]) - Integer.parseInt(s[1]) + 1); + } + dataModel.getJSONObject("v").put("mc", mcData); + } + } + + /** + * @param model sheet页信息 + * @param dataModel 单元格信息 + * @param cell 单元格 + * @param sheet sheet页数据 + * @param workbook excel + * @description 获取单元格样式,设置单元格样式 + * @author zhouhang + * @date 2021/4/21 + */ + private static void dealWithExcelStyle(GridRecordDataModel model, JSONObject dataModel, Cell cell, Sheet sheet, Workbook workbook) { + //设置单元格合并信息 + dealWithExcelMerge(model, sheet); + //设置字体样式 + setFontStyle(dataModel, workbook, cell); + //设置单元格样式 + dealWithBorderStyle(model, cell, workbook); + } + + /** + * @param model 在线表格存储单元 + * @param cell cell + * @param workbook workbook + * @description 设置单元格样式 + * @author zhouhang + * @date 2021/4/22 + */ + private static void dealWithBorderStyle(GridRecordDataModel model, Cell cell, Workbook workbook) { + CellStyle cellStyle = cell.getCellStyle(); + //判断是否存在边框 + if (cellStyle.getBorderTop().getCode() > 0 || cellStyle.getBorderBottom().getCode() > 0 || + cellStyle.getBorderLeft().getCode() > 0 || cellStyle.getBorderRight().getCode() > 0) { + JSONObject border = JSONObject.parseObject(BORDER_MODEL); + border.getJSONObject("value").put("row_index", cell.getRowIndex()); + border.getJSONObject("value").put("col_index", cell.getColumnIndex()); + //xlsx + if (cellStyle instanceof XSSFCellStyle) { + XSSFCellStyle xssfCellStyle = (XSSFCellStyle) cellStyle; + if (Objects.equals((short) 0, cellStyle.getBorderTop().getCode())) { + border.getJSONObject("value").remove("t"); + } else { + border.getJSONObject("value").getJSONObject("t").put("color", dealWithRbg(xssfCellStyle.getTopBorderXSSFColor().getRGB())); + } + if (Objects.equals((short) 0, cellStyle.getBorderRight().getCode())) { + border.getJSONObject("value").remove("r"); + } else { + border.getJSONObject("value").getJSONObject("r").put("color", dealWithRbg(xssfCellStyle.getRightBorderXSSFColor().getRGB())); + } + if (Objects.equals((short) 0, cellStyle.getBorderLeft().getCode())) { + border.getJSONObject("value").remove("l"); + } else { + border.getJSONObject("value").getJSONObject("l").put("color", dealWithRbg(xssfCellStyle.getLeftBorderXSSFColor().getRGB())); + } + if (Objects.equals((short) 0, cellStyle.getBorderBottom().getCode())) { + border.getJSONObject("value").remove("b"); + } else { + border.getJSONObject("value").getJSONObject("b").put("color", dealWithRbg(xssfCellStyle.getBottomBorderXSSFColor().getRGB())); + } + } else if (cellStyle instanceof HSSFCellStyle) { + //xls + HSSFWorkbook hssfWorkbook = (HSSFWorkbook) workbook; + HSSFCellStyle hssfCellStyle = (HSSFCellStyle) cellStyle; + if (Objects.equals((short) 0, cellStyle.getBorderTop().getCode())) { + border.getJSONObject("value").remove("t"); + } else { + HSSFColor color = hssfWorkbook.getCustomPalette().getColor(hssfCellStyle.getTopBorderColor()); + border.getJSONObject("value").getJSONObject("t").put("color", dealWithRbgShort(color.getTriplet())); + } + if (Objects.equals((short) 0, cellStyle.getBorderRight().getCode())) { + border.getJSONObject("value").remove("r"); + } else { + HSSFColor color = hssfWorkbook.getCustomPalette().getColor(hssfCellStyle.getRightBorderColor()); + border.getJSONObject("value").getJSONObject("r").put("color", dealWithRbgShort(color.getTriplet())); + } + if (Objects.equals((short) 0, cellStyle.getBorderLeft().getCode())) { + border.getJSONObject("value").remove("l"); + } else { + HSSFColor color = hssfWorkbook.getCustomPalette().getColor(hssfCellStyle.getLeftBorderColor()); + border.getJSONObject("value").getJSONObject("l").put("color", dealWithRbgShort(color.getTriplet())); + } + if (Objects.equals((short) 0, cellStyle.getBorderBottom().getCode())) { + border.getJSONObject("value").remove("b"); + } else { + HSSFColor color = hssfWorkbook.getCustomPalette().getColor(hssfCellStyle.getBottomBorderColor()); + border.getJSONObject("value").getJSONObject("b").put("color", dealWithRbgShort(color.getTriplet())); + } + } + JSONArray borderInfo = model.getJson_data().getJSONObject("config").getJSONArray("borderInfo"); + if (Objects.isNull(borderInfo)) { + borderInfo = new JSONArray(); + model.getJson_data().getJSONObject("config").put("borderInfo", borderInfo); + } + borderInfo.add(border); + } + } + + /** + * @param rgb RBG short + * @return rbg(0, 0, 0) + * @description 转换RBG rbg(0,0,0) + * @author zhouhang + * @date 2021/4/26 + */ + private static String dealWithRbgShort(short[] rgb) { + return getRbg(Objects.nonNull(rgb), rgb[0], rgb[1], rgb[2]); + } + + @NotNull + private static String getRbg(boolean b2, short r, short b, short g) { + if (b2) { + return "rgb(" + (r & 0xFF) + ", " + (b & 0xFF) + ", " + (g & 0xFF) + ")"; + } else { + return "rgb(0, 0, 0)"; + } + } + + /** + * @param rgb RBG byte + * @return rbg(0, 0, 0) + * @description 转换RBG rbg(0,0,0) + * @author zhouhang + * @date 2021/4/26 + */ + private static String dealWithRbg(byte[] rgb) { + if (Objects.isNull(rgb)) { + return "rgb(0, 0, 0)"; + } + short[] shorts = new short[]{rgb[0], rgb[1], rgb[2]}; + return getRbg(true, shorts[0], shorts[1], shorts[2]); + } + + /** + * @param dataModel 单元格内容 + * @param workbook workbook + * @param cell cell + * @description s设置字体样式 + * @author zhouhang + * @date 2021/4/21 + */ + private static void setFontStyle(JSONObject dataModel, Workbook workbook, Cell cell) { + CellStyle cellStyle = cell.getCellStyle(); + Font font = workbook.getFontAt(cellStyle.getFontIndexAsInt()); + JSONObject v = dataModel.getJSONObject("v"); + //ht 水平对齐 水平对齐方式(0=居中,1=左对齐,2=右对齐) excel:左:1 中:2 右:3 未设置:0 + v.put("ht", ExcelCenterStyleEnum.getExcelCenterStyleByExcelCenterCode(cellStyle.getAlignment().getCode()).getOnlineExcelCode()); + //bl 字体加粗设置 + v.put("bl", font.getBold() ? 1 : 0); + //lt 斜体 + v.put("it", font.getItalic() ? 1 : 0); + //ff 字体 + v.put("ff", font.getFontName()); + //fc 字体颜色 + if (font instanceof HSSFFont) { + HSSFFont hssfFont = (HSSFFont) font; + HSSFColor hssfColor = hssfFont.getHSSFColor((HSSFWorkbook) workbook); + if (Objects.nonNull(hssfColor)) { + v.put("fc", ColorUtil.convertRGBToHex(hssfColor.getTriplet()[0], hssfColor.getTriplet()[1], hssfColor.getTriplet()[2])); + } + } else { + XSSFFont xssfFont = (XSSFFont) font; + XSSFColor xssfColor = xssfFont.getXSSFColor(); + if (Objects.nonNull(xssfColor)) { + v.put("fc", "#" + xssfColor.getARGBHex().substring(2)); + } + } + //fs 字体大小 + v.put("fs", font.getFontHeightInPoints()); + //cl 删除线 + v.put("cl", font.getStrikeout() ? 1 : 0); + //ul 下划线 + v.put("un", font.getUnderline()); + //背景色 + String fillColorHex = ColorUtil.getFillColorHex(cell); + if (Objects.nonNull(fillColorHex)) { + v.put("bg", fillColorHex); + } + } + + /** + * @param model sheet页信息 + * @param sheet sheet页 + * @description 设置单元格合并信息 + * @author zhouhang + * @date 2021/4/21 + */ + private static void dealWithExcelMerge(GridRecordDataModel model, Sheet sheet) { + if (CollectionUtils.isNotEmpty(sheet.getMergedRegions())) { + //{"color":"","list_id":"","column":60,"index":"1","jfgird_select_save":[],"rh_height":1790,"visibledatacolumn":[],"scrollTop":0,"block_id":"fblock","rowsplit":[],"visibledatarow":[],"jfgrid_selection_range":{},"name":"Sheet1","celldata":[],"ch_width":4748,"row":84,"scrollLeft":0,"id":364598,"chart":[],"config":{},"order":0,"status":1} + JSONObject jsonObject = model.getJson_data(); + JSONObject config = jsonObject.getJSONObject("config"); + JSONObject merge = new JSONObject(); + for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) { + JSONObject mergeBase = new JSONObject(); + mergeBase.put("r", mergedRegion.getFirstRow()); + mergeBase.put("c", mergedRegion.getFirstColumn()); + mergeBase.put("rs", mergedRegion.getLastRow() - mergedRegion.getFirstRow() + 1); + mergeBase.put("cs", mergedRegion.getLastColumn() - mergedRegion.getFirstColumn() + 1); + merge.put(mergedRegion.getFirstRow() + "_" + mergedRegion.getFirstColumn(), mergeBase); + } + config.put("merge", merge); + } + } +} diff --git a/report-core/src/main/resources/db/migration/V1.0.12__create_excel.sql b/report-core/src/main/resources/db/migration/V1.0.12__create_excel.sql new file mode 100644 index 00000000..771d9e0c --- /dev/null +++ b/report-core/src/main/resources/db/migration/V1.0.12__create_excel.sql @@ -0,0 +1,27 @@ +use +aj_report; + + +CREATE TABLE `gaea_report_excel` +( + `id` bigint(11) NOT NULL AUTO_INCREMENT, + `report_code` varchar(100) DEFAULT NULL COMMENT '报表编码', + `set_codes` varchar(255) DEFAULT NULL COMMENT '数据集编码,以|分割', + `set_param` varchar(1024) DEFAULT NULL COMMENT '数据集查询参数', + `json_str` text COMMENT '报表json串', + `enable_flag` int(1) DEFAULT '1' COMMENT '0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG', + `delete_flag` int(1) DEFAULT '0' COMMENT '0--未删除 1--已删除 DIC_NAME=DELETE_FLAG', + `create_by` varchar(255) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(255) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `version` int(8) DEFAULT NULL COMMENT '版本号', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `UNIQUE_REPORT_CODE` (`report_code`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=215 DEFAULT CHARSET=utf8; + + +UPDATE `aj_report`.`access_authority` SET `parent_target` = 'report', `target` = 'bigScreenManage', `target_name` = '大屏报表', `action` = 'export', `action_name` = '导出大屏', `sort` = 234, `enable_flag` = 1, `delete_flag` = 0, `create_by` = 'admin', `create_time` = '2019-07-23 15:59:40', `update_by` = 'admin', `update_time` = '2019-07-23 15:59:40', `version` = 1 WHERE `id` = 234; + +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (235, 'report', 'bigScreenManage', '大屏报表', 'import', '导入大屏', 235, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (236, 'report', 'excelManage', '表格报表', 'query', '查询报表', 234, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); diff --git a/report-core/src/main/resources/mapper/ReportExcelMapper.xml b/report-core/src/main/resources/mapper/ReportExcelMapper.xml new file mode 100644 index 00000000..a5a50b07 --- /dev/null +++ b/report-core/src/main/resources/mapper/ReportExcelMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/report-core/src/test/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtilTest.java b/report-core/src/test/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtilTest.java new file mode 100644 index 00000000..901c822f --- /dev/null +++ b/report-core/src/test/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtilTest.java @@ -0,0 +1,54 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.LinkedList; +import java.util.List; + + +/** + * Created by raodeming on 2021/8/30. + */ +public class XlsSheetUtilTest { + + + @Test + public void test1(){ + String str="[{\"row\":199,\"name\":\"Sheet1\",\"chart\":[],\"color\":\"\",\"index\":\"1\",\"order\":0,\"column\":70,\"config\":{\"merge\":{},\"rowlen\":{\"118\":19},\"colhidden\":{},\"columnlen\":{},\"customHeight\":{\"3\":1}},\"images\":{},\"status\":1,\"ch_width\":4748,\"rowsplit\":[],\"calcChain\":[],\"hyperlink\":{},\"rh_height\":1790,\"scrollTop\":0,\"scrollLeft\":0,\"visibledatarow\":[],\"dataVerification\":{},\"visibledatacolumn\":[],\"jfgird_select_save\":[{\"row\":[3,3],\"top\":60,\"left\":222,\"width\":73,\"column\":[3,3],\"height\":19,\"top_move\":60,\"left_move\":222,\"row_focus\":3,\"width_move\":73,\"height_move\":19,\"column_focus\":3}],\"jfgrid_selection_range\":{},\"luckysheet_alternateformat_save\":[],\"luckysheet_conditionformat_save\":[],\"id\":4852,\"block_id\":\"fblock\",\"list_id\":\"xc79500#-8803#7c45f52b7d01486d88bc53cb17dcd2c3\",\"celldata\":[{\"c\":2,\"r\":2,\"v\":{\"m\":\"3\",\"v\":3,\"ct\":{\"t\":\"n\",\"fa\":\"General\"}}},{\"c\":1,\"r\":1,\"v\":{\"m\":\"2\",\"v\":2,\"ct\":{\"t\":\"n\",\"fa\":\"General\"}}},{\"c\":0,\"r\":0,\"v\":{\"m\":\"1\",\"v\":1,\"ct\":{\"t\":\"n\",\"fa\":\"General\"}}},{\"c\":2,\"r\":101,\"v\":{\"m\":\"1111\",\"v\":1111,\"ct\":{\"t\":\"n\",\"fa\":\"General\"}}}]},{\"row\":84,\"name\":\"Sheet2\",\"chart\":[],\"color\":\"\",\"index\":\"2\",\"order\":1,\"column\":60,\"config\":{},\"status\":0,\"ch_width\":4748,\"rowsplit\":[],\"rh_height\":1790,\"scrollTop\":0,\"scrollLeft\":0,\"visibledatarow\":[],\"visibledatacolumn\":[],\"jfgird_select_save\":[{\"row\":[1,1],\"top\":20,\"left\":74,\"width\":73,\"column\":[1,1],\"height\":19,\"top_move\":20,\"left_move\":74,\"row_focus\":1,\"width_move\":73,\"height_move\":19,\"column_focus\":1}],\"jfgrid_selection_range\":{},\"id\":4712,\"block_id\":\"fblock\",\"list_id\":\"xc79500#-8803#7c45f52b7d01486d88bc53cb17dcd2c3\",\"celldata\":[{\"c\":1,\"r\":3,\"v\":{\"m\":\"qwe\",\"v\":\"qwe\",\"ct\":{\"t\":\"g\",\"fa\":\"General\"}}},{\"c\":1,\"r\":1,\"v\":{\"m\":\"qwe\",\"v\":\"qwe\",\"ct\":{\"t\":\"g\",\"fa\":\"General\"}}}]},{\"row\":84,\"name\":\"Sheet3\",\"chart\":[],\"color\":\"\",\"index\":\"3\",\"order\":2,\"column\":60,\"config\":{},\"status\":0,\"ch_width\":4748,\"rowsplit\":[],\"rh_height\":1790,\"scrollTop\":0,\"scrollLeft\":0,\"visibledatarow\":[],\"visibledatacolumn\":[],\"jfgird_select_save\":[{\"row\":[13,13],\"top\":260,\"left\":296,\"width\":73,\"column\":[4,4],\"height\":19,\"top_move\":260,\"left_move\":296,\"row_focus\":13,\"width_move\":73,\"height_move\":19,\"column_focus\":4}],\"jfgrid_selection_range\":{},\"id\":4713,\"block_id\":\"fblock\",\"list_id\":\"xc79500#-8803#7c45f52b7d01486d88bc53cb17dcd2c3\",\"celldata\":[{\"c\":5,\"r\":2,\"v\":{\"m\":\"请问王企鹅全文\",\"v\":\"请问王企鹅全文\",\"bl\":1,\"ct\":{\"t\":\"g\",\"fa\":\"General\"}}},{\"c\":2,\"r\":8,\"v\":{\"m\":\"请问请问\",\"v\":\"请问请问\",\"ct\":{\"t\":\"g\",\"fa\":\"General\"},\"it\":1}}]}]"; + str = "[{\"index\":\"Sheet_MeHeksAaWCLh_1630550132889\",\"status\":1,\"jfgird_select_save\":[],\"luckysheet_select_save\":[{\"left\":518,\"width\":73,\"top\":320,\"height\":19,\"left_move\":518,\"width_move\":73,\"top_move\":320,\"height_move\":19,\"row\":[16,16],\"column\":[7,7],\"row_focus\":16,\"column_focus\":7}],\"data\":[[{\"mc\":{\"r\":0,\"c\":0,\"rs\":2,\"cs\":2}},{\"mc\":{\"r\":0,\"c\":0}},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[{\"mc\":{\"r\":0,\"c\":0}},{\"mc\":{\"r\":0,\"c\":0}},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"},null,{\"m\":\"请求\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"请求\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"},{\"v\":\"333\",\"ct\":{\"fa\":\"General\",\"t\":\"n\"},\"m\":\"333\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"bl\":1,\"ht\":\"2\"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]],\"config\":{\"merge\":{\"0_0\":{\"r\":0,\"c\":0,\"rs\":2,\"cs\":2}},\"borderInfo\":[{\"rangeType\":\"range\",\"borderType\":\"border-all\",\"color\":\"#000\",\"style\":\"1\",\"range\":[{\"left\":0,\"width\":147,\"top\":-1,\"height\":40,\"left_move\":0,\"width_move\":147,\"top_move\":0,\"height_move\":39,\"row\":[0,1],\"column\":[0,1],\"row_focus\":0,\"column_focus\":0}]},{\"rangeType\":\"range\",\"borderType\":\"border-outside\",\"color\":\"#000\",\"style\":\"1\",\"range\":[{\"left\":74,\"width\":73,\"top\":80,\"height\":19,\"left_move\":74,\"width_move\":221,\"top_move\":80,\"height_move\":79,\"row\":[4,7],\"column\":[1,3],\"row_focus\":4,\"column_focus\":1}]},{\"rangeType\":\"range\",\"borderType\":\"border-inside\",\"color\":\"#000\",\"style\":\"1\",\"range\":[{\"left\":74,\"width\":73,\"top\":200,\"height\":19,\"left_move\":74,\"width_move\":221,\"top_move\":200,\"height_move\":119,\"row\":[10,15],\"column\":[1,3],\"row_focus\":10,\"column_focus\":1}]},{\"rangeType\":\"range\",\"borderType\":\"border-all\",\"color\":\"#000\",\"style\":\"1\",\"range\":[{\"left\":370,\"width\":73,\"top\":40,\"height\":19,\"left_move\":370,\"width_move\":295,\"top_move\":40,\"height_move\":119,\"row\":[2,7],\"column\":[5,8],\"row_focus\":2,\"column_focus\":5}]},{\"rangeType\":\"cell\",\"value\":{\"row_index\":3,\"col_index\":5,\"l\":{\"color\":\"#000\",\"style\":\"1\"},\"r\":{\"color\":\"#000\",\"style\":\"1\"},\"t\":{\"color\":\"#000\",\"style\":\"1\"},\"b\":{\"color\":\"#000\",\"style\":\"1\"}}},{\"rangeType\":\"cell\",\"value\":{\"row_index\":4,\"col_index\":5,\"l\":{\"color\":\"#000\",\"style\":\"1\"},\"r\":{\"color\":\"#000\",\"style\":\"1\"},\"t\":{\"color\":\"#000\",\"style\":\"1\"},\"b\":{\"color\":\"#000\",\"style\":\"1\"}}},{\"rangeType\":\"cell\",\"value\":{\"row_index\":5,\"col_index\":5,\"l\":{\"color\":\"#000\",\"style\":\"1\"},\"r\":{\"color\":\"#000\",\"style\":\"1\"},\"t\":{\"color\":\"#000\",\"style\":\"1\"},\"b\":{\"color\":\"#000\",\"style\":\"1\"}}},{\"rangeType\":\"cell\",\"value\":{\"row_index\":6,\"col_index\":5,\"l\":{\"color\":\"#000\",\"style\":\"1\"},\"r\":{\"color\":\"#000\",\"style\":\"1\"},\"t\":{\"color\":\"#000\",\"style\":\"1\"},\"b\":{\"color\":\"#000\",\"style\":\"1\"}}},{\"rangeType\":\"cell\",\"value\":{\"row_index\":7,\"col_index\":5,\"l\":{\"color\":\"#000\",\"style\":\"1\"},\"r\":{\"color\":\"#000\",\"style\":\"1\"},\"t\":{\"color\":\"#000\",\"style\":\"1\"},\"b\":{\"color\":\"#000\",\"style\":\"1\"}}}]},\"visibledatarow\":[20,40,60,80,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,520,540,560,580,600,620,640,660,680,700,720,740,760,780,800,820,840,860,880,900,920,940,960,980,1000,1020,1040,1060,1080,1100,1120,1140,1160,1180,1200,1220,1240,1260,1280,1300,1320,1340,1360,1380,1400,1420,1440,1460,1480,1500,1520,1540,1560,1580,1600,1620,1640,1660,1680],\"visibledatacolumn\":[74,148,222,296,370,444,518,592,666,740,814,888,962,1036,1110,1184,1258,1332,1406,1480,1554,1628,1702,1776,1850,1924,1998,2072,2146,2220,2294,2368,2442,2516,2590,2664,2738,2812,2886,2960,3034,3108,3182,3256,3330,3404,3478,3552,3626,3700,3774,3848,3922,3996,4070,4144,4218,4292,4366,4440],\"ch_width\":4560,\"rh_height\":1760,\"luckysheet_selection_range\":[],\"zoomRatio\":1,\"celldata\":[{\"r\":0,\"c\":0,\"v\":{\"mc\":{\"r\":0,\"c\":0,\"rs\":2,\"cs\":2}}},{\"r\":0,\"c\":1,\"v\":{\"mc\":{\"r\":0,\"c\":0}}},{\"r\":1,\"c\":0,\"v\":{\"mc\":{\"r\":0,\"c\":0}}},{\"r\":1,\"c\":1,\"v\":{\"mc\":{\"r\":0,\"c\":0}}},{\"r\":2,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\"}},{\"r\":3,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"}},{\"r\":4,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"}},{\"r\":4,\"c\":7,\"v\":{\"m\":\"请求\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"请求\"}},{\"r\":5,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"ht\":\"0\"}},{\"r\":5,\"c\":6,\"v\":{\"v\":\"333\",\"ct\":{\"fa\":\"General\",\"t\":\"n\"},\"m\":\"333\"}},{\"r\":6,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\"}},{\"r\":7,\"c\":5,\"v\":{\"m\":\"哈哈\",\"ct\":{\"fa\":\"General\",\"t\":\"g\"},\"v\":\"哈哈\",\"bl\":1,\"ht\":\"2\"}}]}]"; + //DBObject dbObject=(DBObject) JSON.parse(str); + List lists=(List ) JSON.parse(str); + + OutputStream out = null; + try { + out = new FileOutputStream("D:\\test.xlsx"); + XlsUtil.exportXlsFile(out, true, lists); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("start"); + } + + + @Test + public void test2(){ + List list = new LinkedList<>(); + list.add("a"); + list.add("b"); + list.add("c"); + list.add("d"); + list.add("e"); + list.add(2, "f"); + //CopyOnWriteArrayList + System.out.println(list); + } + +} diff --git a/report-ui/index.html b/report-ui/index.html index f2b32ba1..fe26f856 100644 --- a/report-ui/index.html +++ b/report-ui/index.html @@ -5,6 +5,22 @@ AJ-Report + + + + + + + + + + + + + + + + diff --git a/report-ui/package.json b/report-ui/package.json index 25549a78..fcb3473e 100644 --- a/report-ui/package.json +++ b/report-ui/package.json @@ -22,11 +22,13 @@ "echarts-gl": "^1.1.1", "element-ui": "^2.9.2", "js-cookie": "2.2.0", + "jsbarcode": "^3.11.4", "miment": "^0.0.9", "moment": "^2.29.1", "monaco-editor": "^0.20.0", "normalize.css": "7.0.0", "nprogress": "0.2.0", + "qrcodejs2": "0.0.2", "sortablejs": "^1.10.2", "uninstall": "0.0.0", "v-chart": "^1.0.0", diff --git a/report-ui/src/assets/iconfont/iconfont.css b/report-ui/src/assets/iconfont/iconfont.css index 408fa57e..da1b1f50 100644 --- a/report-ui/src/assets/iconfont/iconfont.css +++ b/report-ui/src/assets/iconfont/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1513211 */ - src: url('iconfont.woff2?t=1629797734566') format('woff2'), - url('iconfont.woff?t=1629797734566') format('woff'), - url('iconfont.ttf?t=1629797734566') format('truetype'); + src: url("iconfont.woff2?t=1629797734566") format("woff2"), + url("iconfont.woff?t=1629797734566") format("woff"), + url("iconfont.ttf?t=1629797734566") format("truetype"); } .iconfont { @@ -488,4 +488,3 @@ .iconjiantou-copy-copy:before { content: "\e654"; } - diff --git a/report-ui/src/router/index.js b/report-ui/src/router/index.js index db23066a..0b57fe5a 100644 --- a/report-ui/src/router/index.js +++ b/report-ui/src/router/index.js @@ -49,7 +49,7 @@ export const constantRouterMap = [ { path: 'resultset', name: 'resultset', component: () => import('@/views/report/resultset/index'), meta: { title: '数据集', icon: 'iconAPIwangguan', keepAlive: true, requireAuth: true, permission: 'resultsetManage'} }, { path: 'report', name: 'reportIndex', component: () => import('@/views/report/report/index'), meta: { title: '报表管理', icon: 'iconnavicon-ywcs', keepAlive: true, requireAuth: true, permission: 'reportManage'} }, { path: 'bigscreen', name: 'bigscreen', component: () => import('@/views/report/bigscreen/index'), meta: { title: '大屏报表', icon: 'iconchufaqipeizhi-hui', keepAlive: true, requireAuth: true, permission: 'bigScreenManage'}, }, - //{ path: 'excelreport', name: 'excelreport', component: () => import('@/views/report/excelreport/index'), meta: { title: '表格报表', icon: 'iconliebiao', keepAlive: true, requireAuth: true, permission: 'excelManage'} }, + { path: 'excelreport', name: 'excelreport', component: () => import('@/views/report/excelreport/index'), meta: { title: '表格报表', icon: 'iconliebiao', keepAlive: true, requireAuth: true, permission: 'excelManage'} }, ] }, { @@ -62,6 +62,8 @@ export const constantRouterMap = [ }, { path: '/bigscreen/viewer', component: () => import('@/views/report/bigscreen/viewer'), hidden: true, meta: { requireAuth: true }}, { path: '/bigscreen/designer', component: () => import('@/views/report/bigscreen/designer'), hidden: true, meta: { requireAuth: true }}, + { path: '/excelreport/viewer', component: () => import('@/views/report/excelreport/viewer'), hidden: true, meta: { requireAuth: true }}, + { path: '/excelreport/designer', component: () => import('@/views/report/excelreport/designer'), hidden: true, meta: { requireAuth: true }}, { path: '/404', component: () => import('@/views/404'), hidden: true }, { path: '*', redirect: '/login', hidden: true }, /* diff --git a/report-ui/src/views/report/bigscreen/designer/index.vue b/report-ui/src/views/report/bigscreen/designer/index.vue index 1ca306ae..bdc5415e 100644 --- a/report-ui/src/views/report/bigscreen/designer/index.vue +++ b/report-ui/src/views/report/bigscreen/designer/index.vue @@ -87,7 +87,7 @@ - + - +