This commit is contained in:
linfso 2024-07-23 05:58:08 +08:00
parent 99ee80fcc8
commit 01b417ff2c
24 changed files with 1017 additions and 21 deletions

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: cglib:cglib:3.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba:easyexcel:2.2.7">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/easyexcel/2.2.7/easyexcel-2.2.7.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/easyexcel/2.2.7/easyexcel-2.2.7-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/easyexcel/2.2.7/easyexcel-2.2.7-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.github.virtuald:curvesapi:1.04">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/virtuald/curvesapi/1.04/curvesapi-1.04.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/github/virtuald/curvesapi/1.04/curvesapi-1.04-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/virtuald/curvesapi/1.04/curvesapi-1.04-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-collections4:4.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-collections4/4.1/commons-collections4-4.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-collections4/4.1/commons-collections4-4.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-collections4/4.1/commons-collections4-4.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-compress:1.21">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-compress/1.21/commons-compress-1.21.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-compress/1.21/commons-compress-1.21-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-compress/1.21/commons-compress-1.21-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.poi:poi:3.17">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.17/poi-3.17.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.17/poi-3.17-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.17/poi-3.17-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.poi:poi-ooxml:3.17">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml/3.17/poi-ooxml-3.17.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml/3.17/poi-ooxml-3.17-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml/3.17/poi-ooxml-3.17-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.poi:poi-ooxml-schemas:3.17">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml-schemas/3.17/poi-ooxml-schemas-3.17.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml-schemas/3.17/poi-ooxml-schemas-3.17-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml-schemas/3.17/poi-ooxml-schemas-3.17-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.ehcache:ehcache:3.9.9">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ehcache/ehcache/3.9.9/ehcache-3.9.9.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ehcache/ehcache/3.9.9/ehcache-3.9.9-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ehcache/ehcache/3.9.9/ehcache-3.9.9-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.ow2.asm:asm:4.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -112,15 +112,6 @@
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.79" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
@ -160,7 +151,6 @@
<orderEntry type="library" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
<orderEntry type="library" name="Maven: com.aliyun.oss:aliyun-sdk-oss:3.10.2" level="project" />
@ -266,5 +256,17 @@
<orderEntry type="library" name="Maven: com.aliyun:tea-util:0.2.14" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.9" level="project" />
<orderEntry type="library" name="Maven: com.aliyun:tea:1.1.14" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:easyexcel:2.2.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: cglib:cglib:3.1" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:4.2" level="project" />
<orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.9" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
</component>
</module>

View File

@ -11,13 +11,16 @@
package com.xdadan.erp.web.emis;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.xdadan.erp.emis.domain.EmisSettleSubBill;
import com.xdadan.erp.emis.domain.EmisSettleSubBillFeeitem;
import com.xdadan.erp.emis.domain.exception.EmisBizError;
import com.xdadan.erp.emis.domain.vo.scan.ScanResult;
import com.xdadan.erp.emis.service.EmisBaseService;
import com.xdadan.erp.emis.service.billexport.ExcelUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
@ -189,6 +192,27 @@ public class EmisSettleBillController extends BaseController
}
@Log(title = "导出账单", businessType = BusinessType.EXPORT)
@GetMapping(value = "/exportBill")
public void exportBill(HttpServletResponse response,String settleBillNo)
{
// return AjaxResult.success();
EmisSettleBill bill=emisBaseService.getSettleBillBySettleBillNo(settleBillNo);
List<EmisSettleSubBill> list = emisBaseService.selectSubBillListBySettleBillNo(settleBillNo);
ExcelUtil<EmisSettleSubBill> util = new ExcelUtil<EmisSettleSubBill>(EmisSettleSubBill.class);
// util.exportExcel(response, list, "账单明细数据");
try {
ExcelUtils.exportToTemplate(response, "tpl/settle_bill_tpl.xls", bill.getSettleBillName()+".xls", null,
null, null,
null);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 修改结算总账单

View File

@ -65,15 +65,6 @@
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.79" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
@ -85,7 +76,6 @@
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.16" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.16" level="project" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.6.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.10.0" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.74.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.74.Final" level="project" />
@ -115,7 +105,6 @@
<orderEntry type="library" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
<orderEntry type="library" name="Maven: com.aliyun.oss:aliyun-sdk-oss:3.10.2" level="project" />
@ -137,6 +126,7 @@
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.69" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
<orderEntry type="library" name="Maven: org.xerial.snappy:snappy-java:1.1.8.4" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.14.9" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okio:okio:1.17.2" level="project" />
@ -225,5 +215,17 @@
<orderEntry type="library" name="Maven: com.aliyun:tea-util:0.2.14" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.9" level="project" />
<orderEntry type="library" name="Maven: com.aliyun:tea:1.1.14" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:easyexcel:2.2.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: cglib:cglib:3.1" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:4.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.9" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
</component>
</module>

View File

@ -105,6 +105,26 @@
<version>1.1.14</version>
</dependency>
<!-- alibaba/easyexcel 使用高版本,低版本string接收数字丢小数位的bug -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!-- 江苏移动短信-->
<!-- <dependency>-->
<!-- <groupId>com.mascloud</groupId>-->

View File

@ -1305,6 +1305,11 @@ public class EmisBaseService {
return emisSettleSubBillMapper.setBillErrorBySite(emisSettleSubBill);
}
public List<EmisSettleSubBill> selectSubBillListBySettleBillNo(String settleBillNo){
return emisSettleSubBillMapper.selectSubBillListBySettleBillNo(settleBillNo);
}
/**
* 根据账单号获取总账单
* @param settleBillNo

View File

@ -0,0 +1,50 @@
package com.xdadan.erp.emis.service.billexport;
import lombok.Data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Data
public class DynamicDataMapping {
private String dataId;
private List<Map<String, Object>> dataList;
/**
* @description: 组装只有一个list类型的动态数据
* @param dataId
* @param dataList
*/
public static List<DynamicDataMapping> createOneDataList(String dataId, List<Map<String, Object>> dataList) {
if (dataList == null)
return null;
return Collections.singletonList(getDynamicDataMapping(dataId,dataList));
}
/**
* @description: 组装只有多个list类型的动态数据
* @param transMap
*/
public static List<DynamicDataMapping> createMorDataList(Map<String,List<Map<String, Object>>> transMap) {
if (transMap == null)
return null;
List<DynamicDataMapping> list = new ArrayList<>();
transMap.forEach((dataId,dataList)->{
list.add(getDynamicDataMapping(dataId,dataList));
});
return list;
}
public static DynamicDataMapping getDynamicDataMapping(String dataId, List<Map<String, Object>> dataList){
DynamicDataMapping dynamicData = new DynamicDataMapping();
dynamicData.dataId = dataId;
dynamicData.dataList = dataList;
return dynamicData;
}
}

View File

@ -0,0 +1,70 @@
package com.xdadan.erp.emis.service.billexport;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 列合并工具类
*
* @author DaiHaijiao
*/
public class ExcelFillCellMergePrevColUtils implements CellWriteHandler {
private static final String KEY = "%s-%s";
//所有的合并信息都存在了这个map里面
Map<String, Integer> mergeInfo = new HashMap<>();
public ExcelFillCellMergePrevColUtils() {
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
Integer num = mergeInfo.get(String.format(KEY, curRowIndex, curColIndex));
if (null != num) {
// 合并最后一行 ,列
this.mergeWithPrevCol(writeSheetHolder, cell, curRowIndex, curColIndex, num);
}
}
public void mergeWithPrevCol(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex, int num) {
Sheet sheet = writeSheetHolder.getSheet();
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, curColIndex, curColIndex + num);
sheet.addMergedRegion(cellRangeAddress);
}
//num从第几列开始增加多少列,(6,2,7)代表的意思就是第6行的第2列至第2+7也就是9列开始合并
public void add(int curRowIndex, int curColIndex, int num) {
mergeInfo.put(String.format(KEY, curRowIndex, curColIndex), num);
}
}

View File

@ -0,0 +1,110 @@
package com.xdadan.erp.emis.service.billexport;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.List;
/**
* 行合并工具类
*
* @author DaiHaijiao
*/
public class ExcelFillCellMergeStrategyUtils implements CellWriteHandler {
/**
* 合并字段的下标
*/
private int[] mergeColumnIndex;
/**
* 合并几行
*/
private int mergeRowIndex;
public ExcelFillCellMergeStrategyUtils(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
this.mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
//获取当前行的第一列
Cell firstNowCell = cell.getSheet().getRow(curRowIndex).getCell(curColIndex);
Object curData = firstNowCell.getCellTypeEnum() == CellType.STRING ? firstNowCell.getStringCellValue() : firstNowCell.getNumericCellValue();
Row preRow = cell.getSheet().getRow(curRowIndex - 1);
if (preRow == null) {
// 当获取不到上一行数据时,使用缓存sheet中数据
preRow = writeSheetHolder.getCachedSheet().getRow(curRowIndex - 1);
}
Cell preCell = preRow.getCell(curColIndex);
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
// 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
if (curData.equals(preData)) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一个单元格未被合并,则新增合并单元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
}

View File

@ -0,0 +1,251 @@
package com.xdadan.erp.emis.service.billexport;
import com.xdadan.erp.emis.service.billexport.DynamicDataMapping;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* @Description 根据模版导出Excel程序
*/
public class ExcelTemplateProc {
/**
* @param templateFileName
* @param exportFilePathAndName
* @param staticDataMap
* @param dynamicDataMappingList
* @return void
* @description: 根据模版导出Excel入口
* @author susu
* @date 2024/2/20
*/
public static void doExportExcelByTemplateProc(String templateFileName, String exportFilePathAndName,
Map<String, Object> staticDataMap,
List<DynamicDataMapping> dynamicDataMappingList) throws IOException {
/**
* 1. 从resources下加载模板并替换
* 使用 ResourceUtils 加载文件
*/
File file = ResourceUtils.getFile("classpath:"+templateFileName);
InputStream inputStream = new FileInputStream(file);
Workbook workbook = dealFirstSheetByTemplate(inputStream, staticDataMap, dynamicDataMappingList);
// 2. 保存到本地
saveExportFile(workbook, exportFilePathAndName);
}
/**
* @param workbook
* @param excelFilePath
* @return void
* @description: 保存导出的Excel文件到服务器
* @author susu
* @date 2024/2/20
*/
public static void saveExportFile(Workbook workbook, String excelFilePath) throws IOException {
FileOutputStream outputStream = new FileOutputStream(excelFilePath);
executeWorkBookWrite(workbook, outputStream);
}
/**
* @param workbook
* @param outputStream
* @return void
* @description: 数据输出
* @author susu
* @date 2024/2/20
*/
public static void executeWorkBookWrite(Workbook workbook, OutputStream outputStream) throws IOException {
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
workbook.close();
}
/**
* @param inputStream
* @param staticDataMap
* @param dynamicDataMappingList
* @return org.apache.poi.ss.usermodel.Workbook
* @description: 处理只有一个sheet页的模版
* @author susu
* @date 2024/2/20
*/
public static Workbook dealFirstSheetByTemplate(InputStream inputStream,
Map<String, Object> staticDataMap,
List<DynamicDataMapping> dynamicDataMappingList) throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = workbook.getSheetAt(0);
// 按模板处理sheet页
dealSheetDataByTemplate(sheet, staticDataMap, dynamicDataMappingList);
return workbook;
}
/**
* @param sheet
* @param staticDataMap
* @param dynamicDataMappingList
* @return void
* @description: 按模板处理sheet页里的数据
* @author susu
* @date 2024/2/19
*/
private static void dealSheetDataByTemplate(XSSFSheet sheet, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) {
// 循环sheet里每一行
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
XSSFRow row = sheet.getRow(i);
DynamicDataMapping dynamicDataMapping = getDynamicRowDataByMatch(row, dynamicDataMappingList);
if (dynamicDataMapping != null) {
i = getTemplateLastRowIndexAfterDealTemplate(sheet, i, dynamicDataMapping);
} else {
dealTemplateDataRow(row, null, staticDataMap);
}
}
}
/**
* @param row
* @param dataMap
* @param dataPrefix
* @return void
* @description: 循环处理模版中每行的数据
* @author susu
* @date 2024/2/20
*/
private static void dealTemplateDataRow(XSSFRow row, String dataPrefix, Map<String, Object> dataMap) {
if (dataMap == null) {
return;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
XSSFCell cell = row.getCell(i);
fillInTemplateCellDataValue(cell, dataPrefix, dataMap);
}
}
/**
* @param cell
* @param dataPrefix
* @param dataMap
* @return void
* @description: 填充模版里单元格的值
* @author susu
* @date 2024/2/20
*/
private static void fillInTemplateCellDataValue(XSSFCell cell, String dataPrefix, Map<String, Object> dataMap) {
if (cell == null) {
return;
}
String cellValue = cell.getStringCellValue();//获取模版里设置的数据
if (StringUtils.isEmpty(cellValue)) {
return;
}
boolean flag = false;
dataPrefix = StringUtils.isEmpty(dataPrefix) ? "" : (dataPrefix + ".");
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
// 循环所有,因为可能一行有多个占位符
String cellTemplateStr = "{{" + dataPrefix + entry.getKey() + "}}";
if (cellValue.contains(cellTemplateStr)) {
// 替换模版中单元格的数据
cellValue = cellValue.replace(cellTemplateStr, entry.getValue() == null ? "" : entry.getValue().toString());
flag = true;
}
}
if (flag) {
cell.setCellValue(cellValue);
}
}
/**
* @param row
* @param dynamicDataMappingList
* @return com.liu.susu.excel.template.poi.common.DynamicDataMapping
* @description: 通过模版sheet中的行数据 与 动态数据匹配,获取此行需要填充的动态数据
* @author susu
* @date 2024/2/21
*/
private static DynamicDataMapping getDynamicRowDataByMatch(XSSFRow row, List<DynamicDataMapping> dynamicDataMappingList) {
if (dynamicDataMappingList == null || dynamicDataMappingList.size() < 1) {
return null;
}
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
XSSFCell cell = row.getCell(j);
String value = cell.getStringCellValue();
if (value != null) {
for (DynamicDataMapping dynamicData : dynamicDataMappingList) {
if (value.startsWith("{{" + dynamicData.getDataId() + ".")) {
return dynamicData;
}
}
}
}
return null;
}
/**
* @param sheet
* @param rowIndex
* @param dynamicDataMapping
* @return int
* @description: 根据动态数据的条数动态复制模版行,每处理一个类型的list返回最后的行数,进而处理下一个类型的list
* @author susu
* @date 2024/2/20
*/
private static int getTemplateLastRowIndexAfterDealTemplate(XSSFSheet sheet, int rowIndex, DynamicDataMapping dynamicDataMapping) {
if (dynamicDataMapping == null) {
return rowIndex;
}
int dataRows = dynamicDataMapping.getDataList().size();
// 需要拷贝的行数(因为模板行本身占1行,所以-1)
int copyRows = dataRows - 1;
if (copyRows > 0) {
/**
* shiftRows: 从动态数据模版行(rowIndex)到最后一行,这些全部行都向下移copyRows行
* 相当于模版行上面插入n行空行(n=copyRows)
*/
sheet.shiftRows(rowIndex, sheet.getLastRowNum(), copyRows, true, false);
// 拷贝策略
CellCopyPolicy cellCopyPolicy = makeCellCopyPolicy();
// 因为从模版行开始向下平移了copyRows行,所以这里 模板行=rowIndex + copyRows,
int templateDataRow = rowIndex + copyRows;
// 因为模版行上新增了空行,所以要把模板所在行的模版 拷贝到上面新增的空行
for (int i = 0; i < copyRows; i++) {
//templateDataRow-模版行数据 rowIndex + i循环的当前空行
sheet.copyRows(templateDataRow, templateDataRow, rowIndex + i, cellCopyPolicy);
}
}
// 循环模版行:动态替换模版行(将模版行里的模版替换成动态数据)
for (int j = rowIndex; j < rowIndex + dataRows; j++) {
Map<String, Object> dataMap = dynamicDataMapping.getDataList().get(j - rowIndex);
dealTemplateDataRow(sheet.getRow(j), dynamicDataMapping.getDataId(), dataMap);
}
return rowIndex + copyRows;
}
/**
* @param
* @return org.apache.poi.ss.usermodel.CellCopyPolicy
* @description: 拷贝策略
* @author susu
* @date 2024/2/20
*/
public static CellCopyPolicy makeCellCopyPolicy() {
CellCopyPolicy cellCopyPolicy = new CellCopyPolicy();
cellCopyPolicy.setCopyCellValue(true);
cellCopyPolicy.setCopyCellStyle(true);
return cellCopyPolicy;
}
}

View File

@ -0,0 +1,157 @@
package com.xdadan.erp.emis.service.billexport;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* excel导出工具类
*
*/
public class ExcelUtils {
/**
* 导出数据到指定Excel
*
* @param response HttpServletResponse对象
* @param excelPath Excel模板地址
* @param excelFileName 文件名称
* @param outerMap 头部内容map
* @param innerMapList 表格内容list
* @param excelFillCellMergePrevColUtils 列合并参数
* @param excelFillCellMergeStrategyUtils 行合并参数
* @throws IOException 异常错误
*/
public static void exportToTemplate(HttpServletResponse response, String excelPath, String excelFileName, Map<String, Object> outerMap, List<Map<String, Object>> innerMapList,
ExcelFillCellMergePrevColUtils excelFillCellMergePrevColUtils, ExcelFillCellMergeStrategyUtils excelFillCellMergeStrategyUtils) throws IOException {
InputStream inputStream = new ClassPathResource(excelPath).getInputStream();
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(excelFileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
.withTemplate(inputStream)
.registerWriteHandler(excelFillCellMergePrevColUtils)
.registerWriteHandler(excelFillCellMergeStrategyUtils)
.build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
if (null != innerMapList && innerMapList.size() > 0) {
FillWrapper listWrapper = new FillWrapper("list", innerMapList);
excelWriter.fill(listWrapper, fillConfig, writeSheet);
}
if (null != outerMap && outerMap.size() > 0) {
excelWriter.fill(outerMap, writeSheet);
}
excelWriter.finish();
}
/**
* 验证并获取excel单元格内的值
*
* @param columnData 列值,object类型
* @param rowIndex 行号
* @param columnIndex 列号
* @param fieldName 字段名称
* @param lengthLimit 限制长度数(null时不做判断)
* @param ifJudgeEmpty 是否需要判空(默认是)
* @return 字符串格式值
* @throws Exception 逻辑异常
*/
public static String checkValue(Object columnData, int rowIndex, int columnIndex, String fieldName, Integer lengthLimit,
Boolean ifJudgeEmpty) throws Exception {
String value = getStringValue(columnData);
ifJudgeEmpty = null == ifJudgeEmpty ? true : ifJudgeEmpty;
if (ifJudgeEmpty) {
//需要判空
if (StringUtils.isEmpty(value)) {
throw new Exception("第" + (rowIndex + 1) + "行,第" + (columnIndex + 1) + "列," + fieldName + "不能为空");
}
}
if (null != lengthLimit && lengthLimit > 0) {
//需要判断字符长度
if (StringUtils.isNotEmpty(value)) {
if (value.length() > lengthLimit) {
throw new Exception("第" + (rowIndex + 1) + "行,第" + (columnIndex + 1) + "列," + fieldName + "不能超过" + lengthLimit + "个字符");
}
}
}
return value;
}
/**
* String => LocalDate
* 入参str和pattern格式需要对应
*
* @param str
* @return LocalDate
*/
public static LocalDate str2LocalDate(String str) {
if (StringUtils.isEmpty(str)) {
return null;
}
if (str.indexOf("-") != -1 || str.indexOf("/") != -1) {
String pattern = str.indexOf("/") != -1 ? "yyyy/MM/dd" : "yyyy-MM-dd";
try {
//测试日期字符串是否符合日期
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
return LocalDate.parse(str, dateTimeFormatter);
} catch (Exception e) {
pattern = str.indexOf("/") != -1 ? "yyyy/M/d" : "yyyy-M-d";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
return LocalDate.parse(str, dateTimeFormatter);
}
} else {
Calendar calendar = new GregorianCalendar(1900, 0, -1);
Date date = calendar.getTime();
int amount = Integer.parseInt(str);
if (amount > 0) {
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(date);
calendar1.add(Calendar.DAY_OF_YEAR, amount);
date = calendar.getTime();
}
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
}
/**
* 获取String类型的值
*
* @param columnData 列值,object类型
* @return 字符串格式值
*/
public static String getStringValue(Object columnData) {
if (columnData == null) {
return null;
} else {
String res = columnData.toString().replace("[\\t\\n\\r]", "").trim();
return res;
// //判断是否是科学计数法 true是科学计数法,false不是科学计数法
// boolean isMache=SCIENTIFIC_COUNTING_METHOD_PATTERN.matcher(res).matches();
// if(isMache){
// BigDecimal resDecimal = new BigDecimal(res);
// return resDecimal.toPlainString();
// }else {
// return res;
// }
}
}
public static void main(String[] args) {
// ExcelUtils.exportToTemplate(response, "excel/某某管理导入模板.xlsx", "某某管理导入模板", null, null, null, null);
}
}

View File

@ -0,0 +1,65 @@
package com.xdadan.erp.emis.service.billexport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description 根据模版导出Excel工具类
* @Author susu
* @Date 2024/2/19
*/
public class ExportExcelByTemplateUtils {
/**
* @description: 根据模版导出Excel入口(单个list数据)
* @param templateFileName
* @param exportFilePathAndName
* @param staticDataMap
* @param dataId
* @param originDataList
* @return void
* @author susu
* @date 2024/2/21
*/
public static void doExportExcelOneListByTemplate(String templateFileName, String exportFilePathAndName,
Map<String, Object> staticDataMap,
String dataId,
List<?> originDataList) throws Exception{
List<Map<String, Object>> exportDataList = MapObjectUtil.objListToMapList(originDataList);
// 只有一个list数据
List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createOneDataList(dataId, exportDataList);
// 导出
ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticDataMap,dynamicDataMappingList);
}
/**
* @description: 根据模版导出Excel入口(多个list数据)
* @param templateFileName
* @param exportFilePathAndName
* @param staticSource
* @param originDataMapList
* @return void
* @author susu
* @date 2024/2/20
*/
public static void doExportExcelMoreListByTemplate(String templateFileName,
String exportFilePathAndName,
Map<String, Object> staticSource,
Map<String, List<?>> originDataMapList) throws Exception{
Map<String,List<Map<String, Object>>> transMap = new HashMap<>();
originDataMapList.forEach((dataId,originDataList)->{
List<Map<String, Object>> transDataList = MapObjectUtil.objListToMapList(originDataList);
transMap.put(dataId,transDataList);
});
// 多个list类型数据
List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createMorDataList(transMap);
// 导出
ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticSource,dynamicDataMappingList);
}
}

View File

@ -0,0 +1,97 @@
package com.xdadan.erp.emis.service.billexport;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanMap;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description
* @Author susu
* @Date 2024/2/19
*/
public class MapObjectUtil {
/**
* @description: 将object的list数据 转换成 map的list(如:List<Map<String, Object>>)
* @param objDataList
* @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
* @author susu
*/
public static List<Map<String, Object>> objListToMapList(List<?> objDataList){
List<Map<String, Object>> dataList = new ArrayList<>();
if (objDataList==null || objDataList.size()<1){
return null;
}
objDataList.forEach(obj->{
try {
Map<String, Object> map = MapObjectUtil.objectToMap(obj);
dataList.add(map);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
return dataList;
}
/**
* @description: 将object数据转换成map数据
* @param obj
* @return java.util.Map<java.lang.String,java.lang.Object>
* @author susu
*/
public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
Map<String, Object> map = new HashMap();
Class<?> cla = obj.getClass();
Field[] fields = cla.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String keyName = field.getName();
Object value = field.get(obj);
if (value == null)
value = "";
map.put(keyName, value);
}
return map;
}
/**
* @description: 使用 JSONObject 将object转换成map
* @param obj
* @return java.util.Map<?,?>
* @author susu
*/
public static Map<?, ?> objectToMap2(Object obj) {
if (obj == null)
return null;
return JSONObject.parseObject(JSONObject.toJSONString(obj),Map.class);
}
/**
* @description: 使用BeanMap将object转换成map
* @param obj
* @return java.util.Map<?,?>
* @author susu
*/
public static Map<?, ?> objectToMap3(Object obj) {
if (obj == null)
return null;
return new BeanMap(obj);
}
public static void main(String[] args) {
// DogEntity2 dog = new DogEntity2();
// dog.setDogId("A-1001");
// dog.setDogAge(3);
// dog.setDogName("aaa");
//// Map map = JSONObject.parseObject(JSONObject.toJSONString(dog),Map.class);
// Map map = objectToMap2(dog);
// System.out.println(map);
}
}

Binary file not shown.