本帖最后由 HK仅輝 于 2022-2-21 13:43 编辑
这是一个demo,内有不足请谅解
这个demo的主题是 使用EasyExcel把数据库导出为excel,多少条为一个excel文件,并把这些文件打包到一个固定位置,然后下载这个包文件
目前各种参数都是写死的,使用的是 生产消费者模式 在一个队列中放数据,取数据
放一下关键代码
启动项目时启动一个线程
[Java] 纯文本查看 复制代码 @Component//被spring容器管理
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("-------------->" + "项目启动,now=" + new Date());
ExcelThread.startExcelThread();
}
}
这是一个全局的阻塞队列
[Java] 纯文本查看 复制代码 public class QueueUtil {
public static BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
public static Object get() throws Exception{
// return queue.poll(2, TimeUnit.SECONDS); //不阻塞
return queue.take(); //阻塞
}
public static void put(Object obj) throws Exception{
queue.put(obj);
}
}
这是Controller 中的导出方法,传一个表名进来,条件可选
[Java] 纯文本查看 复制代码 @RequestMapping(value = {"/export/{tableName}"})
public void export(@PathVariable String tableName ,String name){
// System.out.println(tableName+"---"+name.length()); user---0
if (name.length()==0){
service.exportZIP(tableName);
}else {
service.exportZIP(tableName, name);
}
}
这是Service 这里往队列中存入数据
[Java] 纯文本查看 复制代码 public void exportZIP(String tableName){
try {
QueueUtil.put(tableName);
}catch (Exception e){
e.printStackTrace();
System.out.println("存入数据失败");
}
}
public void exportZIP(String tableName,String name){
try {
QueueUtil.put(tableName+":"+name);
}catch (Exception e){
e.printStackTrace();
System.out.println("存入数据失败");
}
}
线程类 在这把队列中的数据取出来
[Java] 纯文本查看 复制代码 public class ExcelThread extends Thread{
private static String PATH ="/file/";
private static String ExcelName = "用户信息表";
private static String TYPE = ".xlsx";
// @Value("${zip.name}")
private static String ZIP_NAME = "用户信息";
private static int SIZE = 5000 ;
private BlockingQueue queue = QueueUtil.queue;
public static ExcelThread excelThread = null;
private FilesService filesservice = (FilesService) ApplicationContextUtil.getBean("filesServiceImpl");
public static void startExcelThread(){
if (excelThread==null){
excelThread = new ExcelThread();
}
excelThread.start();
}
@Override
public void run() {
try {
while (true) {
String str = (String) QueueUtil.get(); //《============
String[] split = str.split(":");
zip(split);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void zip(String[] str) {
OutputStream outputStream;
ZipOutputStream zipOutputStream;
Service service = (Service) ApplicationContextUtil.getBean(str[0]+"ServiceImpl");
long date = System.currentTimeMillis();
ZIP_NAME += date;
String path = System.getProperty("user.dir") + PATH + ZIP_NAME+".zip";
filesservice.alter();
int id = filesservice.save(new Files(ZIP_NAME,new Date(date)));
try {
outputStream = new FileOutputStream(path);
zipOutputStream = new ZipOutputStream(outputStream);
int count = 0;
if (str.length>1){
count = service.count(str[1]);
}else {
count = service.count();
}
count = count/SIZE+(count%SIZE == 0 ?0:1);
for (Integer i = 0; i < count; i++) {
byte[] buf = new byte[1024];
List<User> userList;
if (str.length>1){
userList = service.selectPage(i+1,5000,str[1]);
}else {
userList = service.selectPage(i+1,5000).getRecords();
}
byte[] content = new FileUtil().excelTableStream(userList).toByteArray(); //返回一个excel文件
ByteArrayInputStream is = new ByteArrayInputStream(content);
BufferedInputStream bis = new BufferedInputStream(is);
zipOutputStream.putNextEntry(new ZipEntry(ExcelName+(i+1)+TYPE)); //压缩文件条目
int len;
while ((len = bis.read(buf)) > 0) {
zipOutputStream.write(buf, 0, len);
}
zipOutputStream.closeEntry();
bis.close();
is.close();
zipOutputStream.flush();
System.out.println(ExcelName+(i+1)+TYPE+"导出完成");
}
zipOutputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
filesservice.updateState(id,PATH+ZIP_NAME+".zip");
}
}
public static void main(String[] args) {
Date now = new Date(); // 创建一个Date对象,获取当前时间
// 指定格式化格式
SimpleDateFormat f = new SimpleDateFormat("yyyy年MM月dd日 HH点mm分ss秒");
System.out.println(f.format(now)); // 将当前时间袼式化为指定的格式
}
}
把一个结果集生产一个excel
[Java] 纯文本查看 复制代码 public ByteArrayOutputStream excelTableStream(List<User> userList) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
EasyExcel.write(byteArrayOutputStream, User.class)
//.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) 自动列宽 数字不起作用
.sheet("用户信息")
.doWrite(() -> {
// 查询数据
return userList;
});
return byteArrayOutputStream;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
先上效果图,在列表页面点击导出按钮,然后在一个文件表中添加一条数据,查看导出状态,完成后有一个下载地址 |