feat: 导出账单
This commit is contained in:
parent
1de5af34de
commit
9264ea26d3
|
@ -44,5 +44,10 @@
|
|||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>1.6.14</version>
|
||||
</dependency>
|
||||
<!-- easyexcel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -37,4 +37,5 @@ public class BillDto {
|
|||
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
private LocalDate endDate;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package cn.bunny.dao.dto.financial.bill;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "BillExportDto对象", title = "导出账单信息", description = "导出账单信息")
|
||||
public class BillExportDto {
|
||||
|
||||
@Schema(name = "userId", title = "绑定的用户id")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name = "startDate", title = "开始交易日期")
|
||||
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@NotNull(message = "开始日期不能为空")
|
||||
private LocalDate startDate;
|
||||
|
||||
@Schema(name = "endDate", title = "结束交易日期")
|
||||
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@NotNull(message = "结束日期不能为空")
|
||||
private LocalDate endDate;
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package cn.bunny.dao.dto.financial.bill.user;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
|
@ -24,23 +25,28 @@ public class BillAddUserDto {
|
|||
@NotNull(message = "类型不能为空")
|
||||
@Min(value = -1, message = "类型格式不正确")
|
||||
@Max(value = 1, message = "类型格式不正确")
|
||||
@ExcelProperty(index = 0)
|
||||
private Byte type;
|
||||
|
||||
@Schema(name = "amount", title = "金额")
|
||||
@NotNull(message = "金额不能为空")
|
||||
@Min(value = 0, message = "金额格式不正确")
|
||||
@ExcelProperty("金额")
|
||||
private BigDecimal amount;
|
||||
|
||||
@Schema(name = "description", title = "描述")
|
||||
@ExcelProperty("描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "transactionDate", title = "交易日期")
|
||||
@NotNull(message = "交易日期不能为空")
|
||||
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ExcelProperty("交易日期")
|
||||
private LocalDateTime transactionDate;
|
||||
|
||||
@Schema(name = "categoryId", title = "类别id")
|
||||
@NotNull(message = "类别id不能为空")
|
||||
@ExcelProperty("类别id")
|
||||
private Long categoryId;
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package cn.bunny.dao.excel;
|
||||
|
||||
import cn.bunny.dao.common.vo.BaseVo;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "BillUserVo对象", title = "用户账单信息返回内容", description = "用户账单信息返回内容")
|
||||
public class BillUserExportExcel extends BaseVo {
|
||||
|
||||
@Schema(name = "username", title = "类型:1 - 收入,-1 - 支出")
|
||||
@ExcelProperty("类型:1 - 收入,-1 - 支出")
|
||||
private String type;
|
||||
|
||||
@Schema(name = "amount", title = "金额")
|
||||
@ExcelProperty("金额")
|
||||
private BigDecimal amount;
|
||||
|
||||
@Schema(name = "description", title = "描述")
|
||||
@ExcelProperty("描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "transactionDate", title = "交易日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonSerialize(using = LocalDateTimeSerializer.class)
|
||||
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
|
||||
@ExcelProperty("交易日期")
|
||||
private LocalDateTime transactionDate;
|
||||
|
||||
@Schema(name = "categoryName", title = "类别分类")
|
||||
@ExcelProperty("类别分类")
|
||||
private String categoryName;
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package cn.bunny.dao.vo.financial.user;
|
||||
|
||||
import cn.bunny.dao.common.vo.BaseVo;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
@ -23,18 +24,22 @@ import java.time.LocalDateTime;
|
|||
public class BillUserVo extends BaseVo {
|
||||
|
||||
@Schema(name = "username", title = "类型:1 - 收入,-1 - 支出")
|
||||
@ExcelProperty(index = 0)
|
||||
private Byte type;
|
||||
|
||||
@Schema(name = "amount", title = "金额")
|
||||
@ExcelProperty("金额")
|
||||
private BigDecimal amount;
|
||||
|
||||
@Schema(name = "description", title = "描述")
|
||||
@ExcelProperty("描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "transactionDate", title = "交易日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonSerialize(using = LocalDateTimeSerializer.class)
|
||||
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
|
||||
@ExcelProperty("交易日期")
|
||||
private LocalDateTime transactionDate;
|
||||
|
||||
@Schema(name = "categoryId", title = "分类Id")
|
||||
|
@ -43,6 +48,7 @@ public class BillUserVo extends BaseVo {
|
|||
private String categoryId;
|
||||
|
||||
@Schema(name = "categoryName", title = "类别分类")
|
||||
@ExcelProperty("类别分类")
|
||||
private String categoryName;
|
||||
|
||||
}
|
||||
|
|
7
pom.xml
7
pom.xml
|
@ -39,6 +39,7 @@
|
|||
<velocity.version>2.2</velocity.version>
|
||||
<velocity-tools.version>3.1</velocity-tools.version>
|
||||
<HikariCP.version>5.1.0</HikariCP.version>
|
||||
<easyexcel.version>4.0.2</easyexcel.version>
|
||||
<dynamic.datasource.version>4.3.1</dynamic.datasource.version>
|
||||
<jackson-dataType.version>2.12.3</jackson-dataType.version>
|
||||
<quartz-scheduler.version>2.3.2</quartz-scheduler.version>
|
||||
|
@ -151,6 +152,12 @@
|
|||
<artifactId>quartz</artifactId>
|
||||
<version>${quartz-scheduler.version}</version>
|
||||
</dependency>
|
||||
<!-- Excel表操作 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<version>${easyexcel.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
@ -84,12 +84,6 @@
|
|||
<artifactId>spring-context-support</artifactId>
|
||||
<version>6.1.6</version>
|
||||
</dependency>
|
||||
<!-- Excel表操作 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<version>4.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cn.bunny.services.controller.financial;
|
||||
|
||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||
import cn.bunny.dao.dto.financial.bill.BillExportDto;
|
||||
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||
|
@ -18,6 +19,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -67,13 +69,25 @@ public class BillController {
|
|||
return Mono.just(Result.success(pageResult));
|
||||
}
|
||||
|
||||
@Operation(summary = "账单收入和支出", description = "账单收入和支出")
|
||||
@Operation(summary = "账单收入和支出图表展示", description = "账单收入和支出图表展示")
|
||||
@GetMapping("noManage/getExpendOrIncome")
|
||||
public Mono<Result<ExpendWithIncomeListVo>> getExpendOrIncome(ExpendWithIncomeDto dto) {
|
||||
ExpendWithIncomeListVo vo = billService.getExpendOrIncome(dto);
|
||||
return Mono.just(Result.success(vo));
|
||||
}
|
||||
|
||||
@Operation(summary = "导出用户账单信息", description = "导出用户账单信息")
|
||||
@PostMapping("noManage/exportBill")
|
||||
public void exportBill(@Valid @RequestBody BillExportDto dto, HttpServletResponse response) {
|
||||
billService.exportBill(dto, response);
|
||||
}
|
||||
|
||||
@Operation(summary = "管理员导出账单信息", description = "管理员导出账单信息")
|
||||
@PostMapping("exportBillByAdmin")
|
||||
public void exportBillByAdmin(@Valid @RequestBody BillExportDto dto, HttpServletResponse response) {
|
||||
billService.exportBillByAdmin(dto, response);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加账单信息", description = "添加账单信息")
|
||||
@PostMapping("addBill")
|
||||
public Mono<Result<String>> addBill(@Valid @RequestBody BillAddDto dto) {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package cn.bunny.services.excel;
|
||||
|
||||
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BillAddUserDAO {
|
||||
public void save(List<BillAddUserDto> list) {
|
||||
// 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package cn.bunny.services.excel;
|
||||
|
||||
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.read.listener.ReadListener;
|
||||
import com.alibaba.excel.util.ListUtils;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class BillAddUserListener implements ReadListener<BillAddUserDto> {
|
||||
|
||||
private static final int BATCH_COUNT = 100;
|
||||
private final BillAddUserDAO billAddUserDAO;
|
||||
private List<BillAddUserDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
|
||||
|
||||
public BillAddUserListener() {
|
||||
billAddUserDAO = new BillAddUserDAO();
|
||||
}
|
||||
|
||||
public BillAddUserListener(BillAddUserDAO billAddUserDAO) {
|
||||
this.billAddUserDAO = billAddUserDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个每一条数据解析都会来调用
|
||||
*
|
||||
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
|
||||
*/
|
||||
@Override
|
||||
public void invoke(BillAddUserDto data, AnalysisContext context) {
|
||||
log.info("解析到一条数据:{}", JSON.toJSONString(data));
|
||||
cachedDataList.add(data);
|
||||
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
|
||||
if (cachedDataList.size() >= BATCH_COUNT) {
|
||||
saveData();
|
||||
// 存储完成清理 list
|
||||
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有数据解析完成了 都会来调用
|
||||
*/
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext context) {
|
||||
saveData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加上存储数据库
|
||||
*/
|
||||
private void saveData() {
|
||||
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
|
||||
billAddUserDAO.save(cachedDataList);
|
||||
log.info("存储数据库成功!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package cn.bunny.services.factory;
|
||||
|
||||
import cn.bunny.common.service.exception.BunnyException;
|
||||
import cn.bunny.dao.dto.financial.bill.BillExportDto;
|
||||
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||
import cn.bunny.dao.excel.BillUserExportExcel;
|
||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;
|
||||
import cn.bunny.services.mapper.financial.BillMapper;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Component
|
||||
public class BillFactory {
|
||||
|
||||
@Autowired
|
||||
private BillMapper billMapper;
|
||||
|
||||
public void exportBill(BillExportDto dto, HttpServletResponse response) {
|
||||
LocalDate startDate = dto.getStartDate();
|
||||
LocalDate endDate = dto.getEndDate();
|
||||
|
||||
// 设置日期范围
|
||||
String dateRange = startDate + "~" + endDate;
|
||||
|
||||
// 导出后的文件名
|
||||
String filename = URLEncoder.encode(dateRange, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||
|
||||
// 初始化查询条件,将日期向后移一天查询包含当前的数据
|
||||
ExpendWithIncomeDto expendWithIncomeDto = new ExpendWithIncomeDto();
|
||||
BeanUtils.copyProperties(dto, expendWithIncomeDto);
|
||||
expendWithIncomeDto.setEndDate(endDate.plusDays(1));
|
||||
|
||||
// 设置收入和支出的值
|
||||
AtomicReference<BigDecimal> income = new AtomicReference<>(new BigDecimal(0));
|
||||
AtomicReference<BigDecimal> expend = new AtomicReference<>(new BigDecimal(0));
|
||||
|
||||
// 查询数据
|
||||
List<ExpendWithIncome> expendWithIncomeList = billMapper.selectListByExpendWithIncomeDto(expendWithIncomeDto);
|
||||
List<BillUserExportExcel> excelList = expendWithIncomeList.stream().map(expendWithIncome -> {
|
||||
BillUserExportExcel billUserExportExcel = new BillUserExportExcel();
|
||||
BeanUtils.copyProperties(expendWithIncome, billUserExportExcel);
|
||||
|
||||
// 设置收支类型
|
||||
String type;
|
||||
if (expendWithIncome.getType().equals(Byte.parseByte("1"))) {
|
||||
type = "收入";
|
||||
income.updateAndGet(amount -> amount.add(expendWithIncome.getAmount()));
|
||||
} else {
|
||||
type = "支出";
|
||||
expend.updateAndGet(bigDecimal -> bigDecimal.add(expendWithIncome.getAmount()));
|
||||
}
|
||||
billUserExportExcel.setType(type);
|
||||
|
||||
return billUserExportExcel;
|
||||
}).toList();
|
||||
|
||||
// 查找模板文件
|
||||
String filenameTemplate = Objects.requireNonNull(getClass().getResource("/static/bill-template.xlsx")).getFile();
|
||||
if (filenameTemplate == null) throw new BunnyException(ResultCodeEnum.MISSING_TEMPLATE_FILES);
|
||||
|
||||
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(filenameTemplate).build()) {
|
||||
// 填充数据
|
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
||||
excelWriter.fill(excelList, writeSheet);
|
||||
|
||||
// 写入模板数据
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("dateRange", dateRange);
|
||||
map.put("income", income.get());
|
||||
map.put("expend", expend.get());
|
||||
map.put("profit", income.get().subtract(expend.get()));
|
||||
excelWriter.fill(map, writeSheet);
|
||||
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + filename + ".xlsx");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package cn.bunny.services.service.financial;
|
||||
|
||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||
import cn.bunny.dao.dto.financial.bill.BillExportDto;
|
||||
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||
|
@ -13,6 +14,7 @@ import cn.bunny.dao.vo.financial.user.BillUserVo;
|
|||
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncomeListVo;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -89,4 +91,20 @@ public interface BillService extends IService<Bill> {
|
|||
* @return 账单收入和支出
|
||||
*/
|
||||
ExpendWithIncomeListVo getExpendOrIncome(ExpendWithIncomeDto dto);
|
||||
|
||||
/**
|
||||
* 导出用户账单
|
||||
*
|
||||
* @param dto 日期选择
|
||||
* @param response 响应体
|
||||
*/
|
||||
void exportBill(BillExportDto dto, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 管理员导出账单信息
|
||||
*
|
||||
* @param dto 日期选择
|
||||
* @param response 响应体
|
||||
*/
|
||||
void exportBillByAdmin(BillExportDto dto, HttpServletResponse response);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package cn.bunny.services.service.financial.impl;
|
|||
import cn.bunny.common.service.context.BaseContext;
|
||||
import cn.bunny.common.service.exception.BunnyException;
|
||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||
import cn.bunny.dao.dto.financial.bill.BillExportDto;
|
||||
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||
|
@ -16,6 +17,7 @@ import cn.bunny.dao.vo.financial.user.BillUserVo;
|
|||
import cn.bunny.dao.vo.financial.user.expendAndIncome.CategoryAmount;
|
||||
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;
|
||||
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncomeListVo;
|
||||
import cn.bunny.services.factory.BillFactory;
|
||||
import cn.bunny.services.factory.HomeFactory;
|
||||
import cn.bunny.services.mapper.financial.BillMapper;
|
||||
import cn.bunny.services.service.financial.BillService;
|
||||
|
@ -23,6 +25,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
|||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -44,6 +47,8 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
|
|||
|
||||
@Autowired
|
||||
private HomeFactory homeFactory;
|
||||
@Autowired
|
||||
private BillFactory billFactory;
|
||||
|
||||
/**
|
||||
* * 账单信息 服务实现类
|
||||
|
@ -208,6 +213,30 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
|
|||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出用户账单
|
||||
*
|
||||
* @param dto 日期选择
|
||||
* @param response 返回响应
|
||||
*/
|
||||
@Override
|
||||
public void exportBill(BillExportDto dto, HttpServletResponse response) {
|
||||
dto.setUserId(BaseContext.getUserId());
|
||||
billFactory.exportBill(dto, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 管理员导出账单信息
|
||||
*
|
||||
* @param dto 日期选择
|
||||
* @param response 响应体
|
||||
*/
|
||||
@Override
|
||||
public void exportBillByAdmin(BillExportDto dto, HttpServletResponse response) {
|
||||
billFactory.exportBill(dto, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除账单信息
|
||||
*
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
select *
|
||||
from t_bill b left join t_category tc on b.category_id = tc.id
|
||||
<where>
|
||||
<if test="dto.userId != null and dto.userId != ''">
|
||||
<if test="dto.userId != null">
|
||||
and b.user_id = #{dto.userId}
|
||||
</if>
|
||||
<if test="dto.type != null">
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,84 @@
|
|||
package cn.bunny.services.service.financial.impl;
|
||||
|
||||
import cn.bunny.common.service.exception.BunnyException;
|
||||
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||
import cn.bunny.dao.excel.BillUserExportExcel;
|
||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;
|
||||
import cn.bunny.services.mapper.financial.BillMapper;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@SpringBootTest
|
||||
class BillServiceImplTest {
|
||||
@Autowired
|
||||
private BillMapper billMapper;
|
||||
|
||||
@Test
|
||||
void exportBill() {
|
||||
// 设置数据库查询时间
|
||||
ExpendWithIncomeDto expendWithIncomeDto = new ExpendWithIncomeDto();
|
||||
expendWithIncomeDto.setUserId(1849444494908125181L);
|
||||
expendWithIncomeDto.setStartDate(LocalDate.of(2024, 11, 1));
|
||||
expendWithIncomeDto.setEndDate(LocalDate.of(2024, 11, 30));
|
||||
|
||||
// 设置日期范围
|
||||
String dateRange = expendWithIncomeDto.getStartDate() + "~" + expendWithIncomeDto.getEndDate();
|
||||
|
||||
// 设置收入和支出的值
|
||||
AtomicReference<BigDecimal> income = new AtomicReference<>(new BigDecimal(0));
|
||||
AtomicReference<BigDecimal> expend = new AtomicReference<>(new BigDecimal(0));
|
||||
|
||||
// 查询数据
|
||||
List<ExpendWithIncome> expendWithIncomeList = billMapper.selectListByExpendWithIncomeDto(expendWithIncomeDto);
|
||||
List<BillUserExportExcel> excelList = expendWithIncomeList.stream().map(expendWithIncome -> {
|
||||
BillUserExportExcel billUserExportExcel = new BillUserExportExcel();
|
||||
BeanUtils.copyProperties(expendWithIncome, billUserExportExcel);
|
||||
|
||||
// 设置收支类型
|
||||
String type;
|
||||
if (expendWithIncome.getType().equals(Byte.parseByte("1"))) {
|
||||
type = "收入";
|
||||
income.updateAndGet(amount -> amount.add(expendWithIncome.getAmount()));
|
||||
} else {
|
||||
type = "支出";
|
||||
expend.updateAndGet(bigDecimal -> bigDecimal.add(expendWithIncome.getAmount()));
|
||||
}
|
||||
billUserExportExcel.setType(type);
|
||||
|
||||
return billUserExportExcel;
|
||||
}).toList();
|
||||
|
||||
String filenameTemplate = Objects.requireNonNull(getClass().getResource("/static/bill-template.xlsx")).getFile();
|
||||
if (filenameTemplate == null) throw new BunnyException(ResultCodeEnum.MISSING_TEMPLATE_FILES);
|
||||
|
||||
try (ExcelWriter excelWriter = EasyExcel.write("F:\\数据库备份\\" + dateRange + ".xlsx").withTemplate(filenameTemplate).build()) {
|
||||
// 填充数据
|
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
||||
excelWriter.fill(excelList, writeSheet);
|
||||
|
||||
// 写入模板数据
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("dateRange", dateRange);
|
||||
map.put("income", income.get());
|
||||
map.put("expend", expend.get());
|
||||
map.put("profit", income.get().subtract(expend.get()));
|
||||
excelWriter.fill(map, writeSheet);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package excel.fill;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
public class FillTest {
|
||||
|
||||
@Test
|
||||
void fillTest1() {
|
||||
// // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
// String filenameTemplate = "F:\\数据库备份\\bill-template.xlsx";
|
||||
//
|
||||
// // 设置数据库查询时间
|
||||
// BillExportDto billExportDto = new BillExportDto();
|
||||
// billExportDto.setUserId(1849444494908125181L);
|
||||
// billExportDto.setStartDate(LocalDate.of(2024, 11, 1));
|
||||
// billExportDto.setEndDate(LocalDate.of(2024, 11, 30));
|
||||
//
|
||||
// EasyExcel.write("F:\\数据库备份\\" + billExportDto.getStartDate() + "~" + billExportDto.getEndDate() + ".xlsx").withTemplate(filenameTemplate).sheet().doFill(fillData);
|
||||
|
||||
// // 方案2 根据Map填充
|
||||
// fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
|
||||
// // 这里 会填充到第一个sheet, 然后文件流会自动关闭
|
||||
// Map<String, Object> map = MapUtils.newHashMap();
|
||||
// map.put("name", "张三");
|
||||
// map.put("number", 5.2);
|
||||
// EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue