import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/export")
@ResponseBody
public void export(@RequestParam Map<String, Object> params, HttpServletResponse response) {
System.out.println("导出测试,params={}" + JSONObject.toJSONString(params));
// 设置 Content-Type 头部信息
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// 设置 Content-Disposition 头部信息,指定文件名
response.setHeader("Content-Disposition", "attachment; filename=\"example.xlsx\"");
try {
// 通过 Apache POI 创建 Workbook 对象并向 HttpServletResponse 的输出流中写入数据
//Workbook workbook = createExcelWorkbook(); // 创建 Workbook 对象的方法需要根据具体业务逻辑来实现
/**
* 将上述代码直接放在一个 Web 应用程序中,可能会出现响应断开的问题。
* 这是因为在处理 HTTP 请求时,需要确保在将响应发送给客户端之前,所有的数据都已经写入到输出流中。
*/
// 解决:把 createExcelWorkbook()放入异步中
// 创建1个异步任务,每个任务返回一个结果
CompletableFuture<XSSFWorkbook> workbookFuture = CompletableFuture.supplyAsync(() -> {
XSSFWorkbook workbook = null;
try {
// 生成表格
workbook = createExcelWorkbook();
} catch (Exception e) {
e.printStackTrace();
}
return workbook;
});
// 使用allOf等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(workbookFuture);
// 当所有任务完成后,可以进一步处理结果
CompletableFuture<XSSFWorkbook> finalResult = allFutures.thenApply(v -> {
try {
// 获取并处理所有任务的结果
XSSFWorkbook workbook = workbookFuture.get();
return workbook;
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
// 阻塞等待最终结果
XSSFWorkbook workbook = finalResult.get();
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
} catch (IOException e) {
// 处理异常
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public XSSFWorkbook createExcelWorkbook() throws IOException {
// 创建新的 Excel 工作簿
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Images");
// 从 URL 中获取图片数据
URL imageUrl = new URL("https://example.com/image.jpg");
InputStream imageStream = imageUrl.openStream();
byte[] imageBytes = IOUtils.toByteArray(imageStream);
imageStream.close();
// 将图片数据插入到 Excel 中
int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_JPEG);
CreationHelper helper = workbook.getCreationHelper();
Drawing<?> drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(1);
anchor.setRow1(1);
Picture pict = drawing.createPicture(anchor, pictureIdx);
pict.resize(1, 1);
return (XSSFWorkbook) workbook;
}
}
前端请求Java应用导出,使用HttpServletResponse导出时,HttpServletResponse会断开网络的问题记录
于 2024-02-05 16:26:00 首次发布