feat: 导出账单使用Excel导入账单

This commit is contained in:
Bunny 2024-11-27 23:14:16 +08:00
parent 9264ea26d3
commit 5d8f655a5b
15 changed files with 347 additions and 61 deletions

View File

@ -1,4 +1,4 @@
package cn.bunny.dao.dto.financial.bill;
package cn.bunny.dao.dto.financial.bill.excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@ -0,0 +1,42 @@
package cn.bunny.dao.dto.financial.bill.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "BillAddDto对象", title = "账单信息添加内容", description = "账单信息添加内容")
public class BillImportUserDto {
@Schema(name = "username", title = "类型1 - 收入,-1 - 支出")
@ExcelProperty(index = 0)
private String type;
@Schema(name = "amount", title = "金额")
@ExcelProperty("金额")
private BigDecimal amount;
@Schema(name = "description", title = "描述")
@ExcelProperty("描述")
private String description;
@Schema(name = "transactionDate", title = "交易日期")
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty("交易日期")
private LocalDateTime transactionDate;
@Schema(name = "categoryId", title = "类别")
@ExcelProperty("类别")
private String categoryName;
}

View File

@ -1,6 +1,5 @@
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;
@ -25,28 +24,23 @@ 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;
}

View File

@ -1,10 +1,10 @@
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;
import cn.bunny.dao.dto.financial.bill.excel.BillExportDto;
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
import cn.bunny.dao.dto.financial.bill.user.BillUpdateUserDto;
import cn.bunny.dao.entity.financial.Bill;
@ -23,6 +23,7 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Mono;
import java.util.List;
@ -76,6 +77,13 @@ public class BillController {
return Mono.just(Result.success(vo));
}
@Operation(summary = "使用Excel导入用户账单", description = "使用Excel导入用户账单")
@PostMapping("noManage/importBill")
public Mono<Result<Result<String>>> importBill(MultipartFile file) {
billService.importBill(file);
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
}
@Operation(summary = "导出用户账单信息", description = "导出用户账单信息")
@PostMapping("noManage/exportBill")
public void exportBill(@Valid @RequestBody BillExportDto dto, HttpServletResponse response) {

View File

@ -16,6 +16,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.http.ResponseEntity;
@ -83,6 +84,12 @@ public class FilesController {
return filesService.downloadFilesByFilepath(filepath);
}
@Operation(summary = "获取添加账单模板文件", description = "获取添加账单模板文件")
@GetMapping("noManage/getAddBillTemplate")
public void getAddBillTemplate(HttpServletResponse response) {
filesService.getAddBillTemplate(response);
}
// // 无法做权限校验
// @Operation(summary = "根据文件名访问resource下图片文件", description = "根据文件名访问resource下文件")
// @GetMapping("noAuth/getResourceImagesByFilename/{filename}")

View File

@ -1,11 +1,74 @@
package cn.bunny.services.excel;
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.dao.dto.financial.bill.excel.BillImportUserDto;
import cn.bunny.dao.entity.financial.Bill;
import cn.bunny.dao.entity.financial.Category;
import cn.bunny.services.mapper.financial.CategoryMapper;
import cn.bunny.services.service.financial.BillService;
import cn.hutool.core.text.StrBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.BeanUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
public class BillAddUserDAO {
public void save(List<BillAddUserDto> list) {
// 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
public void save(List<BillImportUserDto> cachedDataList, BillService billService, CategoryMapper categoryMapper, StrBuilder messageContent, AtomicReference<Integer> index) {
Long userId = BaseContext.getUserId();
// 查询数据
LambdaQueryWrapper<Category> queryWrapper = Wrappers.<Category>lambdaQuery().eq(Category::getUserId, userId).or().eq(Category::getIsBuiltin, true);
Map<String, Long> categoryMap = categoryMapper.selectList(queryWrapper).stream().collect(Collectors.toMap(Category::getCategoryName, Category::getId));
List<Bill> billList = cachedDataList.stream()
// 判断是否有值
.filter(billImportUserDto -> {
index.updateAndGet(i -> i == null ? 1 : i + 1);
String billImportUserDtoType = billImportUserDto.getType();
BigDecimal amount = billImportUserDto.getAmount();
LocalDateTime transactionDate = billImportUserDto.getTransactionDate();
String categoryName = billImportUserDto.getCategoryName();
if (StringUtils.isEmpty(billImportUserDtoType)
|| amount == null
|| StringUtils.isEmpty(categoryName)
|| transactionDate == null) {
String string = "序号[" + index.get() + "]数据为空--> " + "类型:" + billImportUserDtoType + ", 金额:" + amount + ", 日期:" + transactionDate + ", 类别:" + categoryName + "<br/>";
messageContent.append(string);
return false;
}
return true;
})
.map(billImportUserDto -> {
String billImportUserDtoType = billImportUserDto.getType();
String categoryName = billImportUserDto.getCategoryName();
Bill bill = new Bill();
BeanUtils.copyProperties(billImportUserDto, bill);
// 设置用户id
bill.setUserId(userId);
// 判断添加的类型是否正确
byte type = billImportUserDtoType.equals("收入") ? Byte.parseByte("1") : Byte.parseByte("-1");
bill.setType(type);
// 添加的分类查找分类id
Long categoryId = categoryMap.get(categoryName);
bill.setCategoryId(categoryId);
return bill;
}).toList();
billService.saveBatch(billList);
}
}

View File

@ -1,27 +1,65 @@
package cn.bunny.services.excel;
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.dao.dto.financial.bill.excel.BillImportUserDto;
import cn.bunny.dao.entity.system.Message;
import cn.bunny.dao.entity.system.MessageReceived;
import cn.bunny.services.mapper.financial.CategoryMapper;
import cn.bunny.services.mapper.message.MessageMapper;
import cn.bunny.services.mapper.message.MessageReceivedMapper;
import cn.bunny.services.service.financial.BillService;
import cn.hutool.core.text.StrBuilder;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* 无法被Spring管理必须使用构造函数注入方式
*/
@Slf4j
public class BillAddUserListener implements ReadListener<BillAddUserDto> {
public class BillAddUserListener implements ReadListener<BillImportUserDto> {
// 缓存数据
private static final int BATCH_COUNT = 100;
// 需要存入数据库的数据
private final BillAddUserDAO billAddUserDAO;
private List<BillAddUserDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
// 查询用户类别
private final CategoryMapper categoryMapper;
// 用户消息
private final MessageMapper messageMapper;
// 用户接受消息
private final MessageReceivedMapper messageReceivedMapper;
// 存入数据库信息
private final BillService billService;
private final StrBuilder messageContent = new StrBuilder();
// 设置索引查看是第几个数据异常
AtomicReference<Integer> index = new AtomicReference<>(1);
private List<BillImportUserDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
public BillAddUserListener() {
public BillAddUserListener(CategoryMapper categoryMapper, MessageMapper messageMapper, MessageReceivedMapper messageReceivedMapper, BillService billService) {
billAddUserDAO = new BillAddUserDAO();
this.categoryMapper = categoryMapper;
this.billService = billService;
this.messageMapper = messageMapper;
this.messageReceivedMapper = messageReceivedMapper;
}
public BillAddUserListener(BillAddUserDAO billAddUserDAO) {
this.billAddUserDAO = billAddUserDAO;
@Override
public void onException(Exception exception, AnalysisContext context) {
if (exception instanceof ExcelDataConvertException excelDataConvertException) {
int row = excelDataConvertException.getRowIndex() + 1;
int column = excelDataConvertException.getColumnIndex() + 1;
log.warn("第{}行,第{}列解析异常,请正确填写", row, column);
messageContent.append("").append(String.valueOf(row)).append("行,第").append(String.valueOf(column)).append("列解析异常,请正确填写<br/>");
}
}
/**
@ -30,8 +68,7 @@ public class BillAddUserListener implements ReadListener<BillAddUserDto> {
* @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));
public void invoke(BillImportUserDto data, AnalysisContext context) {
cachedDataList.add(data);
// 达到BATCH_COUNT了需要去存储一次数据库防止数据几万条数据在内存容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
@ -46,15 +83,40 @@ public class BillAddUserListener implements ReadListener<BillAddUserDto> {
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也要保存数据确保最后遗留的数据也存储到数据库
saveData();
if (StringUtils.isBlank(messageContent.toString())) return;
// 获取当前用户id同时也是接受人的id
Long userId = BaseContext.getUserId();
// 将消息中的内容进行Base64编码要求就是这样
String encoded = Base64.getEncoder().encodeToString(messageContent.toString().getBytes());
// 如果有消息
Message message = new Message();
message.setTitle("导入账单时出错");
message.setSendUserId(1L);
message.setMessageType("1851507850609356802");
message.setSummary("导入账单时出错");
message.setContent(encoded);
message.setEditorType("rich");
message.setLevel("warning");
message.setExtra("导入错误");
messageMapper.insert(message);
// 从之前保存的消息中获取消息id保存到消息接收表中
MessageReceived messageReceived = new MessageReceived();
messageReceived.setMessageId(message.getId());
messageReceived.setReceivedUserId(userId);
messageReceived.setStatus(false);
messageReceivedMapper.insert(messageReceived);
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
billAddUserDAO.save(cachedDataList);
log.info("存储数据库成功!");
billAddUserDAO.save(cachedDataList, billService, categoryMapper, messageContent, index);
}
}

View File

@ -1,8 +1,8 @@
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.dto.financial.bill.excel.BillExportDto;
import cn.bunny.dao.excel.BillUserExportExcel;
import cn.bunny.dao.pojo.result.ResultCodeEnum;
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;

View File

@ -1,10 +1,10 @@
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;
import cn.bunny.dao.dto.financial.bill.excel.BillExportDto;
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
import cn.bunny.dao.dto.financial.bill.user.BillUpdateUserDto;
import cn.bunny.dao.entity.financial.Bill;
@ -15,6 +15,7 @@ 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 org.springframework.web.multipart.MultipartFile;
import java.util.List;
@ -107,4 +108,11 @@ public interface BillService extends IService<Bill> {
* @param response 响应体
*/
void exportBillByAdmin(BillExportDto dto, HttpServletResponse response);
/**
* 使用Excel导入用户账单
*
* @param file 文件
*/
void importBill(MultipartFile file);
}

View File

@ -3,10 +3,11 @@ 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;
import cn.bunny.dao.dto.financial.bill.excel.BillExportDto;
import cn.bunny.dao.dto.financial.bill.excel.BillImportUserDto;
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
import cn.bunny.dao.dto.financial.bill.user.BillUpdateUserDto;
import cn.bunny.dao.entity.financial.Bill;
@ -17,10 +18,15 @@ 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.excel.BillAddUserListener;
import cn.bunny.services.factory.BillFactory;
import cn.bunny.services.factory.HomeFactory;
import cn.bunny.services.mapper.financial.BillMapper;
import cn.bunny.services.mapper.financial.CategoryMapper;
import cn.bunny.services.mapper.message.MessageMapper;
import cn.bunny.services.mapper.message.MessageReceivedMapper;
import cn.bunny.services.service.financial.BillService;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -29,7 +35,9 @@ import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
@ -47,9 +55,17 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
@Autowired
private HomeFactory homeFactory;
@Autowired
private BillFactory billFactory;
@Autowired
private CategoryMapper categoryMapper;
@Autowired
private MessageMapper messageMapper;
@Autowired
private MessageReceivedMapper messageReceivedMapper;
/**
* * 账单信息 服务实现类
*
@ -195,7 +211,7 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
// 分类列表
List<CategoryAmount> categoryAmountList = expendWithIncomeList.stream()
.filter(expendWithIncome -> dto.getType() != null && expendWithIncome.getType().equals(dto.getType()))
.filter(expendWithIncome -> dto.getType() != null && expendWithIncome.getType().equals(dto.getType()) && expendWithIncome.getCategoryName() != null)
.collect(Collectors.groupingBy(ExpendWithIncome::getCategoryName,
Collectors.summingDouble(expend -> expend.getAmount().doubleValue()))
).entrySet()
@ -237,6 +253,20 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
billFactory.exportBill(dto, response);
}
/**
* 使用Excel导入用户账单
*
* @param file 文件
*/
@Override
public void importBill(MultipartFile file) {
try {
EasyExcel.read(file.getInputStream(), BillImportUserDto.class, new BillAddUserListener(categoryMapper, messageMapper, messageReceivedMapper, this)).sheet().doRead();
} catch (IOException e) {
throw new BunnyException(ResultCodeEnum.UPDATE_ERROR);
}
}
/**
* 删除|批量删除账单信息
*

View File

@ -10,6 +10,7 @@ import cn.bunny.dao.vo.system.files.FileInfoVo;
import cn.bunny.dao.vo.system.files.FilesVo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
@ -84,4 +85,9 @@ public interface FilesService extends IService<Files> {
* @return 媒体文件类型列表
*/
Set<String> getAllMediaTypes();
/**
* 获取添加账单模板文件
*/
void getAddBillTemplate(HttpServletResponse response);
}

View File

@ -9,18 +9,25 @@ import cn.bunny.dao.dto.system.files.FileUploadDto;
import cn.bunny.dao.dto.system.files.FilesAddDto;
import cn.bunny.dao.dto.system.files.FilesDto;
import cn.bunny.dao.dto.system.files.FilesUpdateDto;
import cn.bunny.dao.entity.financial.Category;
import cn.bunny.dao.entity.system.Files;
import cn.bunny.dao.pojo.common.MinioFilePath;
import cn.bunny.dao.pojo.result.PageResult;
import cn.bunny.dao.pojo.result.ResultCodeEnum;
import cn.bunny.dao.vo.system.files.FileInfoVo;
import cn.bunny.dao.vo.system.files.FilesVo;
import cn.bunny.services.mapper.financial.CategoryMapper;
import cn.bunny.services.mapper.system.FilesMapper;
import cn.bunny.services.service.system.FilesService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 jakarta.validation.Valid;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
@ -38,6 +45,7 @@ import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
@ -63,6 +71,8 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
@Autowired
private FilesMapper filesMapper;
@Autowired
private CategoryMapper categoryMapper;
/**
* * 系统文件表 服务实现类
@ -289,4 +299,32 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
return Set.of();
}
}
/**
* 获取添加账单模板文件
*/
@Override
public void getAddBillTemplate(HttpServletResponse response) {
// 设置数据库查询时间
Long userId = BaseContext.getUserId();
// 查询数据
LambdaQueryWrapper<Category> queryWrapper = Wrappers.<Category>lambdaQuery().eq(Category::getUserId, userId).or().eq(Category::getIsBuiltin, true);
List<Category> categoryList = categoryMapper.selectList(queryWrapper);
String filenameTemplate = Objects.requireNonNull(getClass().getResource("/static/bill-add-template.xlsx")).getFile();
if (filenameTemplate == null) throw new BunnyException(ResultCodeEnum.MISSING_TEMPLATE_FILES);
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(filenameTemplate).build()) {
// 填充数据类型数据要填充的在第二个sheet
WriteSheet writeSheet = EasyExcel.writerSheet(1).build();
excelWriter.fill(categoryList, writeSheet);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + "bill-add-template.xlsx");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -2,13 +2,20 @@ 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.entity.financial.Category;
import cn.bunny.dao.entity.system.Message;
import cn.bunny.dao.entity.system.MessageReceived;
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 cn.bunny.services.mapper.financial.CategoryMapper;
import cn.bunny.services.mapper.message.MessageMapper;
import cn.bunny.services.mapper.message.MessageReceivedMapper;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -16,16 +23,19 @@ 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.*;
import java.util.concurrent.atomic.AtomicReference;
@SpringBootTest
class BillServiceImplTest {
@Autowired
private BillMapper billMapper;
@Autowired
private CategoryMapper categoryMapper;
@Autowired
private MessageMapper messageMapper;
@Autowired
private MessageReceivedMapper messageReceivedMapper;
@Test
void exportBill() {
@ -81,4 +91,52 @@ class BillServiceImplTest {
throw new RuntimeException(e);
}
}
@Test
void downloadAddBillTemplate() {
// 设置数据库查询时间
Long userId = 1849444494908125181L;
// 查询数据
List<Category> categoryList = categoryMapper.selectList(Wrappers.<Category>lambdaQuery().eq(Category::getUserId, userId));
String filenameTemplate = Objects.requireNonNull(getClass().getResource("/static/bill-add-template.xlsx")).getFile();
if (filenameTemplate == null) throw new BunnyException(ResultCodeEnum.MISSING_TEMPLATE_FILES);
try (ExcelWriter excelWriter = EasyExcel.write("F:\\数据库备份\\bill-add-template.xlsx").withTemplate(filenameTemplate).build()) {
// 填充数据
WriteSheet writeSheet = EasyExcel.writerSheet(1).build();
excelWriter.fill(categoryList, writeSheet);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
void addBillByExcel() {
String encoded = Base64.getEncoder().encodeToString("messageContent.toString()".getBytes());
// 如果有消息
Message message = new Message();
message.setTitle("导入账单时出错");
message.setSendUserId(1L);
message.setMessageType("1851507850609356802");
message.setSummary("导入账单时出错");
message.setContent(encoded);
message.setEditorType("rich");
message.setLevel("warning");
message.setExtra("导入错误");
messageMapper.insert(message);
// 从之前保存的消息中获取消息id保存到消息接收表中
// Long userId = BaseContext.getUserId();
Long userId = 1849444494908125181L;
MessageReceived messageReceived = new MessageReceived();
messageReceived.setMessageId(message.getId());
messageReceived.setReceivedUserId(userId);
messageReceived.setStatus(false);
messageReceivedMapper.insert(messageReceived);
}
}

View File

@ -1,30 +0,0 @@
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);
}
}