Browse Source

排队导出

pull/2/head
程序员蜗牛 1 year ago
parent
commit
48abdcc0bb
  1. 77
      排队导出/paiduiexport/paiduiexport/pom.xml
  2. 14
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/DemoRequestScopeApplication.java
  3. 30
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/config/ThreadPoolConfig.java
  4. 93
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/AbstractExport.java
  5. 40
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportController.java
  6. 58
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportImpl.java
  7. 60
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportQueue.java
  8. 8
      排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportUser.java
  9. 3
      排队导出/paiduiexport/paiduiexport/src/main/resources/application.properties

77
排队导出/paiduiexport/paiduiexport/pom.xml

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo-request-scope</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-request-scope</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

14
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/DemoRequestScopeApplication.java

@ -0,0 +1,14 @@
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoRequestScopeApplication {
public static void main(String[] args) {
SpringApplication.run(DemoRequestScopeApplication.class, args);
}
}

30
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/config/ThreadPoolConfig.java

@ -0,0 +1,30 @@
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class ThreadPoolConfig {
private static final int corePoolSize = 10; // 核心线程数
private static final int maximumPoolSize = 20; // 最大线程数
private static final long keepAliveTime = 60L; // 空闲线程存活时间
private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
@Bean
public ThreadPoolExecutor getThreadPoolExecutor() {
return new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TIME_UNIT,
new ArrayBlockingQueue<>(2000),
new ThreadPoolExecutor.AbortPolicy()
);
}
}

93
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/AbstractExport.java

@ -0,0 +1,93 @@
package com.example.demo.export;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.PageUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
@Slf4j
public abstract class AbstractExport<T, K> {
public abstract void export(ExportUser sysUser) throws InterruptedException;
/**
* 导出
* @param response 输出流
* @param pageSize 每页大小
* @param t 导出条件
* @param k Excel内容实体类
* @param fileName 文件名称
*/
public void export(HttpServletResponse response, int pageSize, T t, Class<K> k, String fileName) throws Exception {
ExcelWriter writer = null;
try {
writer = getExcelWriter(response, fileName);
//查询导出总条数
int total = this.countExport(t);
//页数
int loopCount = PageUtil.totalPage(total, pageSize);
BeanUtil.setProperty(t, "pageSize", pageSize);
for (int i = 0; i < loopCount; i++) {
//开始页
BeanUtil.setProperty(t, "pageNum", PageUtil.getStart(i + 1, pageSize));
//获取Excel导出信息
List<K> kList = this.getExportDetail(t);
WriteSheet writeSheet = EasyExcel.writerSheet(fileName).head(k).build();
writer.write(kList, writeSheet);
}
} catch (Exception e) {
String msg = "导出" + fileName + "异常";
log.error(msg, e);
throw new Exception(msg + e);
} finally {
if (writer != null) {
writer.finish();
}
}
}
public ExcelWriter getExcelWriter(HttpServletResponse response, String fileName) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileNameUtf = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameUtf + ".xlsx");
return EasyExcel.write(response.getOutputStream()).build();
}
/**
* 模版导出
*
* @param t
* @param fileName
* @param response
*/
public abstract void complexFillWithTable(T t, String fileName, HttpServletResponse response);
/**
* 查询导出总条数
*
* @param t
* @return
*/
public abstract int countExport(T t);
/**
* 查询导出数据
*
* @param t
* @return
*/
public abstract List<K> getExportDetail(T t);
}

40
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportController.java

@ -0,0 +1,40 @@
package com.example.demo.export;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ThreadPoolExecutor;
@RestController
@RequestMapping("/export")
@Slf4j
public class ExportController {
@Autowired
private ExportImpl export;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
/**
* 实现一个排队导出功能
*/
@PostMapping("/exportFile")
public void exportFile() {
log.info("提交线程池任务");
threadPoolExecutor.execute(() -> {
ExportUser sysUser = new ExportUser();
sysUser.setUserName(Thread.currentThread().getName());
try {
export.export(sysUser);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
);
log.info("提交线程池任务结束");
}
}

58
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportImpl.java

@ -0,0 +1,58 @@
package com.example.demo.export;
import com.alibaba.excel.ExcelWriter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@Service
@Slf4j
public class ExportImpl extends AbstractExport {
@Autowired
private ExportQueue exportQueue;
@Override
public void export(ExportUser sysUser) throws InterruptedException {
//导出
log.info("导出文件方法执行~~~~~~~~~");
LinkedList<ExportUser> queue = exportQueue.add(sysUser);
//可以考虑把队列进行持久化
log.info("导出队列:" + queue);
//export(response,pageSize,t,k,fileName);
//导出成功后移除当前导出用户
ExportUser nextSysUser = exportQueue.getNextSysUser();
log.info("移除后获取下一个排队的用户: " + nextSysUser.getUserName());
}
@Override
public void export(HttpServletResponse response, int pageSize, Object o, Class k, String fileName) throws Exception {
super.export(response, pageSize, o, k, fileName);
}
@Override
public ExcelWriter getExcelWriter(HttpServletResponse response, String fileName) throws IOException {
return super.getExcelWriter(response, fileName);
}
@Override
public void complexFillWithTable(Object o, String fileName, HttpServletResponse response) {
}
@Override
public int countExport(Object o) {
return 0;
}
@Override
public List getExportDetail(Object o) {
return null;
}
}

60
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportQueue.java

@ -0,0 +1,60 @@
package com.example.demo.export;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
@Slf4j
@Component
public class ExportQueue {
private final int MAX_CAPACITY = 10; // 队列最大容量
private LinkedList<ExportUser> queue; // 用户队列 或者阻塞队列 或者 直接消息队列
public ExportQueue(LinkedList<ExportUser> queue) {
this.queue = new LinkedList<>();
}
/**
* 排队队列添加
*
* @param sysUser
*/
public synchronized LinkedList<ExportUser> add(ExportUser sysUser) {
while (queue.size() >= MAX_CAPACITY) {
try {
log.info("当前排队人已满,请等待");
wait();
} catch (InterruptedException e) {
e.getMessage();
}
}
queue.add(sysUser);
log.info("目前导出队列排队人数:" + queue.size());
notifyAll();
return queue;
}
/**
* 获取排队队列下一个人
*
* @return
*/
public synchronized ExportUser getNextSysUser() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ExportUser sysUser = queue.remove();
notifyAll(); //唤醒
return sysUser;
}
}

8
排队导出/paiduiexport/paiduiexport/src/main/java/com/example/demo/export/ExportUser.java

@ -0,0 +1,8 @@
package com.example.demo.export;
import lombok.Data;
@Data
public class ExportUser {
private String userName;
}

3
排队导出/paiduiexport/paiduiexport/src/main/resources/application.properties

@ -0,0 +1,3 @@
spring.redis.host=192.168.56.10
spring.redis.password=123456
Loading…
Cancel
Save