导出数据到excel报connection reset和broken pipe异常

Excel导出Bug
本文介绍了一个Excel导出数据为空的问题及解决办法。该问题源于使用迅雷下载导致的Socket异常,通过改用IE浏览器自带下载器成功解决了问题。

实习时现场的人提出个bug,导出查询数据时,excel表格里是空的,查询数据是有的,通过查看后台,发现报错:

java.net.SocketException: Connection reset
java.net.SocketException: Broken pipe

各种找资料,网上说的多种解决方法,但是我们是用封装好的方法来用的,应该不会出问题,经过排除,测试,发现问题。

问题:导出时下载文件自动跳出迅雷下载,导致报错!
解决方法:不适用迅雷,使用ie自带的下载器下载文件即可解决。

现在我需要将数据excel方式导出 这是我的代码package com.yiwugo.chuneng.util; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.exception.ExcelGenerateException; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.List; public class ExcelExportUtil { public static void exportToExcel(List<?> dataList, String sheetName, HttpServletResponse response) { if (dataList == null || dataList.isEmpty()) { throw new RuntimeException("数据为空,无法导出"); } OutputStream outputStream = null; try { Class<?> clazz = dataList.get(0).getClass(); // 设置响应头,修复导出文件内容乱码问题 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); String encodedFileName = URLEncoder.encode(sheetName, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20"); response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName + ".xlsx"); // 获取输出流 outputStream = response.getOutputStream(); // 检查连接状态,如果已断开则直接返回 if (isClientDisconnected(response)) { System.err.println("客户端已断开连接,取消Excel导出"); return; } // 使用EasyExcel写入数据 EasyExcel.write(outputStream, clazz) .autoCloseStream(false) // 禁用自动关闭流 .head(clazz) .sheet(sheetName) .doWrite(dataList); // 再次检查连接状态,确保可以刷新 if (!isClientDisconnected(response)) { outputStream.flush(); // 通知容器响应已完成 response.flushBuffer(); } } catch (Exception e) { // 统一处理异常 if (isConnectionException(e)) { System.err.println("客户端连接异常Excel导出中断: " + e.getMessage()); return; } else { throw new RuntimeException("导出Excel失败", e); } } finally { // 手动关闭流,但先检查连接状态 if (outputStream != null) { try { // 只有在响应未提交且客户端未断开的情况下才尝试关闭 if (!response.isCommitted() && !isClientDisconnected(response)) { outputStream.close(); } } catch (IOException e) { // 检查是否是连接相关的异常,如果是则忽略 if (!isConnectionException(e)) { System.err.println("关闭输出流时发生异常: " + e.getMessage()); } } } } } /** * 检查客户端是否已断开连接 */ private static boolean isClientDisconnected(HttpServletResponse response) { try { // 通过检查响应是否已提交或是否可以写入来判断 if (response.isCommitted()) { return true; } // 尝试写入一个空字节来检测连接状态 response.getOutputStream().write(new byte[0]); response.getOutputStream().flush(); return false; } catch (IOException e) { return true; } } /** * 判断是否为连接相关异常 */ private static boolean isConnectionException(Throwable throwable) { if (throwable == null) { return false; } // 检查常见的连接异常类型消息 String message = throwable.getMessage(); if (message != null && (message.contains("Broken pipe") || message.contains("Connection reset by peer") || message.contains("已断开连接") || message.contains("closed") || message.contains("Can not close IO"))) { return true; } // 检查异常类型 if (throwable instanceof IOException) { // 检查具体的异常类名(有些框架会包装异常) String className = throwable.getClass().getName(); if (className.contains("BrokenPipe") || className.contains("ConnectionReset") || className.contains("SocketException")) { return true; } } // 检查异常链 return isConnectionException(throwable.getCause()); } } 执行时一直会java.io.IOException : Broken pipe这个错误怎么解决
最新发布
08-26
public static void exportToExcel(List<?> dataList, String sheetName, HttpServletResponse response) { if (dataList == null || dataList.isEmpty()) { throw new RuntimeException("数据为空,无法导出"); } OutputStream outputStream = null; try { Class<?> clazz = dataList.get(0).getClass(); // 设置响应头,修复导出文件内容乱码问题 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); String encodedFileName = URLEncoder.encode(sheetName, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20"); response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName + ".xlsx"); // 获取输出流 outputStream = response.getOutputStream(); // 检查连接状态,如果已断开则直接返回 if (isClientDisconnected(response)) { System.err.println("客户端已断开连接,取消Excel导出"); return; } // 使用EasyExcel写入数据 EasyExcel.write(outputStream, clazz) .autoCloseStream(false) // 禁用自动关闭流 .head(clazz) .sheet(sheetName) .doWrite(dataList); // 再次检查连接状态,确保可以刷新 if (!isClientDisconnected(response)) { outputStream.flush(); // 通知容器响应已完成 response.flushBuffer(); } } catch (Exception e) { // 统一处理异常 if (isConnectionException(e)) { System.err.println("客户端连接异常Excel导出中断: " + e.getMessage()); return; } else { throw new RuntimeException("导出Excel失败", e); } } finally { // 手动关闭流,但先检查连接状态 if (outputStream != null) { try { // 只有在响应未提交且客户端未断开的情况下才尝试关闭 if (!response.isCommitted() && !isClientDisconnected(response)) { outputStream.close(); } } catch (IOException e) { // 检查是否是连接相关的异常,如果是则忽略 if (!isConnectionException(e)) { System.err.println("关闭输出流时发生异常: " + e.getMessage()); } } } } }。 代码会Broken pipe这个错误怎么修改
08-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值