EasyExce简单使用案例
Easyexcel针对导出的订单进行合并
退款系统,导出订单详细信息,订单中有需要合并的列需要对其列中同样的数据进行合并
比如用户ID,一个用户有多个订单所以需要将用户id同样的进行合并,同时从数据库查询出来的话还uid可能不在一起还需要排序处理
主要是实现合并
1、long类型用自带的LongStringConverter转换器处理,给它转换成了字符类型。这里不知道为什么它有默认的转换器没有去转换,而日期自动就去转换了,后面再研究吧
2、CashType、PayStatus、OrderStatus、PayResultStatus、NotifyResultStatus 这些是类的属性,需要我们自己去写转换器进行转换
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class OrderPayModel{
@ColumnWidth(20)
@ExcelProperty({"用户id"})
private long uid;
@ColumnWidth(10)
@ExcelProperty({"余额"})
private int balance;
@ColumnWidth(10)
@ExcelProperty({"赠币"})
private int coupon;
@ColumnWidth(14)
@ExcelProperty({"合计退款"})
private int totalRefundAmount;
@ColumnWidth(14)
@ExcelProperty({"差额"})
private int differenceAmount;
@ColumnWidth(10)
@ExcelProperty({"产品线"})
private String appId;
@ColumnWidth(30)
@ExcelProperty({"订单号"})
private String orderNo;
@ColumnWidth(32)
@ExcelProperty({"外部订单号"})
private String outTradeNo;
@ColumnWidth(12)
@ExcelProperty({"订单金额"})
private Integer amount;
@ColumnWidth(15)
@ExcelProperty({"商品名称"})
private String productName;
@ColumnWidth(20)
@ExcelProperty({"订单创建时间"})
private Date createTime;
@ExcelIgnore
private int payId;
@ColumnWidth(12)
@ExcelProperty({"支付类型"})
private CashType payType;
@ColumnWidth(12)
@ExcelProperty({"付款金额"})
private int payAmount;
@ColumnWidth(12)
@ExcelProperty({"退款金额"})
private int refundAmount;
@ColumnWidth(12)
@ExcelProperty({"是否全退"})
private String isRefundAll;
@ColumnWidth(12)
@ExcelProperty({"支付状态"})
private PayStatus payStatus;
@ColumnWidth(20)
@ExcelProperty({"支付时间"})
private Date payTime;
@ColumnWidth(30)
@ExcelProperty({"交易流水号"})
private String transactionId;
@ColumnWidth(12)
@ExcelProperty({"支付状态"})
private OrderStatus orderStatus;
@ColumnWidth(12)
@ExcelProperty({"支付结果"})
private PayResultStatus payResult;
@ColumnWidth(12)
@ExcelProperty({"通知结果"})
private NotifyResultStatus notifyResult;
}
这个可以参考LoopMergeStrategy和OnceAbsoluteMergeStrategy实现自己想要的功能。
思路:就是拿到需要合并的uid即用户ID以前对其排序,相同的uid放在一起,然后去合并的时候提前预处理一下,把这些需要合并的uid进行分组,分组集合中存放的数字是需要合并的uid合并的行数,默认1不需要合并
注意点
1、继承了AbstractMergeStrategy,它的方法afterCellDispose默认就过滤了头,我们不需要子类去重写它了,因为头已经过滤了,我们只需要重写它的merge方法,自己去定义合并
2、这里我们需要着重的理解下rowIndex,这个是开始合并的初始行,我们利用了跳过了头,从第一行开始,刚好从第一行遍历列到第四列,就合并完成了。以后再进来就不满足条件了。另外这里也可以自己放到外面,比如new对象的时候把它传进来,但是一般都是从第一行开始合并的,所以在类中直接写死了。
3、其他需要注意的点都在代码中注释了。
public class CustomMergeStrategy extends AbstractMergeStrategy {
/**
* 合并的行 分组合并 [1 1 2] 代表第二、三行不需要合并、四五行需要合并成一个单元格
*/
private List<Integer>mergeFieldGroup;
/**
* 目标合并列下标
*/
private List<Integer>targetColumnIndex;
// 合并的行起始 除了头开始合并并且只合并一次(一次就把目标合并的列下所有行统一合并)
private Integer rowIndex;
/**
*
* @param mergeFieldGroup 需要进行合并的uid集合 即 针对集合中相同的uid进行合并
* @param targetColumnIndex 要进行合并的列都有哪些列 即 目标合并列下标
*/
public CustomMergeStrategy(List<String> mergeFieldGroup, List<Integer> targetColumnIndex) {
// 相同的集合需要处理一下 比如 uid集合为[1,1,2,2,2,3] 那么处理后的形成一个分组 [2,3,1]说明第[2~3]、[4~6]需要合并 这里默认头为第一行
this.mergeFieldGroup = mergeFieldGroupFormat(mergeFieldGroup);
this.targetColumnIndex = targetColumnIndex;
}
/**
*
* @param mergeFieldGroup
* 统计每个uid要合并个数
* @return
*/
private List<Integer> mergeFieldGroupFormat(List<String> mergeFieldGroup) {
if(CollectionUtils.isEmpty(mergeFieldGroup)){
return Collections.emptyList();
}
List<Integer>mergeFieldGroupFormat=new ArrayList<>();
//uid需要合并的个数 值为1 的时候不需要合并
int rowCnt=1;
// 从第二个元素开始比较前一个相同 防止指针越界
for (int i = 1; i < mergeFieldGroup.size(); i++) {
if(mergeFieldGroup.get(i).equals(mergeFieldGroup.get(i-1))){
rowCnt++;
}else {
mergeFieldGroupFormat.add(rowCnt);
rowCnt=1;
}
}
mergeFieldGroupFormat.add(rowCnt);
return mergeFieldGroupFormat;
}
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
if(Objects.equals(null,rowIndex)){
//第一次null 开始合并 此后不在合并
rowIndex=cell.getRowIndex();
}
if(cell.getRowIndex()== rowIndex && targetColumnIndex.contains(cell.getColumnIndex())){
mergeGroupColum(sheet,cell.getColumnIndex());
}
}
private void mergeGroupColum(Sheet sheet, int columnIndex) {
// currentRow 当前所在的行
int currentRow=rowIndex;
for(Integer count:mergeFieldGroup){
if(count.equals(1)){//不需要合并
currentRow+=count;// 这里要一直统计当前行位置
continue;
}
// merge cell 参考 LoopMergeStrategy 合并策略
sheet.addMergedRegionUnsafe(new CellRangeAddress(currentRow,currentRow+count-1,columnIndex,columnIndex));
currentRow+=count;
}
}
}
这个主要用来对实体中的属性进行转换
package com.xxx.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.xxx.excel.consts.CashType;
public class CashTypeStringConverter implements Converter<CashType> {
public CashTypeStringConverter() {
}
public Class<CashType> supportJavaTypeKey() {
return CashType.class;
}
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public CashType convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return CashType.from((NumberUtils.parseInteger(cellData.getStringValue(), excelContentProperty)));
}
@Override
public WriteCellData convertToExcelData(CashType value, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return new WriteCellData(value.text);
}
}
package com.xxx.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.xxx.excel.consts.OrderStatus;
public class OrderStatusStringConverter implements Converter<OrderStatus> {
public OrderStatusStringConverter() {
}
@Override
public Class<OrderStatus> supportJavaTypeKey() {
return OrderStatus.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public OrderStatus convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return OrderStatus.from((NumberUtils.parseInteger(cellData.getStringValue(), excelContentProperty)));
}
@Override
public WriteCellData convertToExcelData(OrderStatus value, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return new WriteCellData(value.getText());
}
}
package com.xxx.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.xxx.excel.consts.PayStatus;
public class PayStatusStringConverter implements Converter<PayStatus> {
public PayStatusStringConverter() {
}
@Override
public Class<PayStatus> supportJavaTypeKey() {
return PayStatus.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public PayStatus convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return PayStatus.from((NumberUtils.parseInteger(cellData.getStringValue(), excelContentProperty)));
}
@Override
public WriteCellData convertToExcelData(PayStatus value, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return new WriteCellData(value.getText());
}
}
package com.xxx.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.xxx.excel.consts.PayResultStatus;
public class PayResultStatusStringConverter implements Converter<PayResultStatus> {
public PayResultStatusStringConverter() {
}
@Override
public Class<PayResultStatus> supportJavaTypeKey() {
return PayResultStatus.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public PayResultStatus convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return PayResultStatus.from((NumberUtils.parseInteger(cellData.getStringValue(), excelContentProperty)));
}
@Override
public WriteCellData convertToExcelData(PayResultStatus value, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return new WriteCellData(value.getText());
}
}
package com.xxx.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.xxx.excel.consts.NotifyResultStatus;
public class NotifyResultStatusStringConverter implements Converter<NotifyResultStatus> {
public NotifyResultStatusStringConverter() {
}
@Override
public Class<NotifyResultStatus> supportJavaTypeKey() {
return NotifyResultStatus.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public NotifyResultStatus convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return NotifyResultStatus.from((NumberUtils.parseInteger(cellData.getStringValue(), excelContentProperty)));
}
@Override
public WriteCellData convertToExcelData(NotifyResultStatus value, ExcelContentProperty excelContentProperty
, GlobalConfiguration globalConfiguration) throws Exception {
return new WriteCellData(value.text);
}
}
package com.xxx.excel.consts;
/**
* @author liuyuanyuan on 2022/11/22
* 1. 微信; 2. 支付宝
*/
public enum CashType {
WEIXIN(1, "微信"),
ALIPAY(2,"支付宝"),
APPLE(3,"Apple"),
COIN(11,"钱包"),
UNKNOWN(-1,"unknown");
public int id;
public String text;
CashType(Integer id, String text) {
this.id = id;
this.text = text;
}
public static CashType from(int id) {
for(CashType cashType:CashType.values()){
if(cashType.getId()==id){
return cashType;
}
}
return UNKNOWN;
}
public int getId(){
return id;
}
public String getText(){
return text;
}
}
package com.xxx.excel.consts;
/**
* @author liuyuanyuan on 2022/11/22
*/
public enum NotifyResultStatus {
Normal(0,"初始化"),
Success(1,"通知成功"),
Failure(2,"通知失败"),
UNKNOWN(-1,"UNKNOWN");
public int id;
public String text;
NotifyResultStatus(int id, String text) {
this.id = id;
this.text = text;
}
public int getId() {
return id;
}
public String getText() {
return text;
}
public static NotifyResultStatus from(int id) {
for(NotifyResultStatus notifyResultStatus:NotifyResultStatus.values()){
if(notifyResultStatus.getId()==id){
return notifyResultStatus;
}
}
return UNKNOWN;
}
}
package com.xxx.excel.consts;
/**
* @author liuyuanyuan on 2022/11/22
*/
public enum OrderStatus {
ReceivingOrder(1, "接收订单"),
ToPay(2, "待支付"),
PayCompleted(3, "支付完成"),
TransactionCompleted(4, "交易成功"),
TransactionFailed(5, "交易失败"),
UNKNOWN(-1,"UNKNOWN");
private int id;
private String text;
OrderStatus(int id, String text) {
this.id = id;
this.text = text;
}
public int getId() {
return id;
}
public String getText() {
return text;
}
public static OrderStatus from(int id){
for(OrderStatus orderStatus:OrderStatus.values()){
if(orderStatus.getId()==id){
return orderStatus;
}
}
return UNKNOWN;
}
}
package com.xxx.excel.consts;
/**
* @author liuyuanyuan on 2022/11/22
*/
public enum PayResultStatus {
Normal(0,"初始化"),
Success(1,"支付成功"),
Failure(2,"支付失败"),
UNKNOWN(-1,"UNKNOWN");
private int id;
private String text;
PayResultStatus(int id, String text) {
this.id = id;
this.text = text;
}
public int getId() {
return id;
}
public String getText() {
return text;
}
public static PayResultStatus from(int id){
for(PayResultStatus payResultStatus:PayResultStatus.values()){
if(payResultStatus.getId()==id){
return payResultStatus;
}
}
return UNKNOWN;
}
}
package com.xxx.excel.consts;
/**
* @author liuyuanyuan on 2022/11/22
*/
public enum PayStatus {
ToPay(1,"等待支付"),
Cancel(2,"取消"),
TimeoutOff(3,"超时关闭"),
Success(4,"支付成功"),
RepeatPay(5,"重复支付"),
UNKNOWN(-1,"UNKNOWN")
;
private int id;
private String text;
PayStatus(int id, String text){
this.id=id;
this.text=text;
}
public int getId() {
return id;
}
public String getText() {
return text;
}
public static PayStatus from(int id){
for(PayStatus payStatus:PayStatus.values()){
if(payStatus.getId()==id){
return payStatus;
}
}
return UNKNOWN;
}
}
测试自定义合并策略和自定义转换器
@Test
void custommergeWrite(){
String fileName = path + "custommergeWrite" + System.currentTimeMillis() + ".xlsx";
List<OrderPayModel> orderPayModels = getOrderPayModels();
EasyExcel.write(fileName,OrderPayModel.class)
.registerWriteHandler(new CustomMergeStrategy(orderPayModels.stream().map(model->String.valueOf(model.getUid())).collect(Collectors.toList()),
ListUtils.newArrayList(0,1,2,3,4)))
// 这里是表格中有long类型 需要处理
.registerConverter(new LongStringConverter())
.registerConverter(new CashTypeStringConverter())
.registerConverter(new OrderStatusStringConverter())
.registerConverter(new PayStatusStringConverter())
.registerConverter(new PayResultStatusStringConverter())
.registerConverter(new NotifyResultStatusStringConverter())
.sheet("微信订单")
.doWrite(orderPayModels);
}
这个数据一般是从数据库查询的,这里方便演示,直接模拟了下数据
private List<OrderPayModel> getOrderPayModels(){
String str="[{\n" +
"\"amount\": 3,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 600,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1637551215000,\n" +
"\"differenceAmount\": 507,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211122085596798189568\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"8ac148e52c424a48a19a749fb2e7523f\",\n" +
"\"payAmount\": 3,\n" +
"\"payId\": 204905,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1637551223000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值3000\",\n" +
"\"refundAmount\": 3,\n" +
"\"totalRefundAmount\": 93,\n" +
"\"transactionId\": \"4200001204202111227976892526\",\n" +
"\"uid\": 80000438\n" +
"},{\n" +
"\"amount\": 1,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 3731,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1640764608000,\n" +
"\"differenceAmount\": 3729,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211229120393975201792\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"cb9765a421f640d98619c8a3d648fb12\",\n" +
"\"payAmount\": 1,\n" +
"\"payId\": 205052,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1640764628000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值600\",\n" +
"\"refundAmount\": 1,\n" +
"\"totalRefundAmount\": 2,\n" +
"\"transactionId\": \"4200001385202112298977096001\",\n" +
"\"uid\": 80000705\n" +
"},\n" +
"{\n" +
"\"amount\": 1,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 3731,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1640764500000,\n" +
"\"differenceAmount\": 3729,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211229120167059161088\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"0b79d5c4c3de4ed09f6c3f957cf4ac2c\",\n" +
"\"payAmount\": 1,\n" +
"\"payId\": 205051,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1640764523000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值600\",\n" +
"\"refundAmount\": 1,\n" +
"\"totalRefundAmount\": 2,\n" +
"\"transactionId\": \"4200001381202112294343499890\",\n" +
"\"uid\": 80000705\n" +
"},{\n" +
"\"amount\": 31,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1644477333000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA220210115204503371776\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"af240aa5cf8449cca52cb3b3cc577a01\",\n" +
"\"payAmount\": 31,\n" +
"\"payId\": 205421,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1644477343000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值31\",\n" +
"\"refundAmount\": 31,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001376202202105295797873\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 1,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1641883488000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA220111111334924484608\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"3be05371eda54bcaaeaafd642b26f47a\",\n" +
"\"payAmount\": 1,\n" +
"\"payId\": 205135,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1641883566000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值600\",\n" +
"\"refundAmount\": 1,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001407202201119718948110\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 6,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639641952000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216121534838472704\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"4c376a5938a647518dddb0356e517967\",\n" +
"\"payAmount\": 6,\n" +
"\"payId\": 204962,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639641959000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值19800\",\n" +
"\"refundAmount\": 6,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001415202112164957793301\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 6,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639640989000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216119516438724608\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"41482653f5da45d9a7b53cf138f55b58\",\n" +
"\"payAmount\": 6,\n" +
"\"payId\": 204961,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639640999000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值19800\",\n" +
"\"refundAmount\": 6,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001415202112165188105829\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 5,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639639915000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216117263384444928\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"e27b9504591647bc95934bc0ce505f5d\",\n" +
"\"payAmount\": 5,\n" +
"\"payId\": 204959,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639639929000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值9800\",\n" +
"\"refundAmount\": 5,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001141202112168829269532\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 6,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639635870000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216108779391680512\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"bf5c583f3fb74d38a9b8f58571366dea\",\n" +
"\"payAmount\": 6,\n" +
"\"payId\": 204957,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639635880000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值19800\",\n" +
"\"refundAmount\": 6,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001117202112162971443118\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 2,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639626282000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216088673385185280\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"34a22de2ae4f47e6a808eb61c0fb2ca3\",\n" +
"\"payAmount\": 2,\n" +
"\"payId\": 204956,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639626289000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值1200\",\n" +
"\"refundAmount\": 2,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001396202112165178615963\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 1,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639626250000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211216088605340991488\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"fbdd9875217e4140a463394f810cf7bd\",\n" +
"\"payAmount\": 1,\n" +
"\"payId\": 204955,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639626258000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值600\",\n" +
"\"refundAmount\": 1,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001385202112168103181024\",\n" +
"\"uid\": 1296377728268080892\n" +
"},{\n" +
"\"amount\": 2,\n" +
"\"appId\": \"101\",\n" +
"\"balance\": 77,\n" +
"\"coupon\": 0,\n" +
"\"createTime\": 1639551949000,\n" +
"\"differenceAmount\": 17,\n" +
"\"isRefundAll\": \"全退\",\n" +
"\"notifyResult\": \"Success\",\n" +
"\"orderNo\": \"TDYA211215113978585907200\",\n" +
"\"orderStatus\": \"TransactionCompleted\",\n" +
"\"outTradeNo\": \"39597284a464433a9583e6f52c231661\",\n" +
"\"payAmount\": 2,\n" +
"\"payId\": 204949,\n" +
"\"payResult\": \"Success\",\n" +
"\"payStatus\": \"Success\",\n" +
"\"payTime\": 1639551956000,\n" +
"\"payType\": \"WEIXIN\",\n" +
"\"productName\": \"充值1200\",\n" +
"\"refundAmount\": 2,\n" +
"\"totalRefundAmount\": 60,\n" +
"\"transactionId\": \"4200001235202112158640023642\",\n" +
"\"uid\": 1296377728268080892\n" +
"}\n" +
"\n]";
return JSONArray.parseArray(str,OrderPayModel.class).stream().sorted(Comparator.comparing(OrderPayModel::getUid))
.collect(Collectors.toList());
}