首页 > 开发 > Java > 正文

java web开发中大量数据导出Excel超时(504)问题解决

2024-07-13 10:06:23
字体:
来源:转载
供稿:网友
import java.io.IOException;import java.io.OutputStream;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;import org.joda.time.DateTime;import com.travelzen.framework.net.http.TZHttpClient;import com.travelzen.tops.front.ota.member.item.CustomerItem;public class CSV {  /**   * 目标输出流   */  private OutputStream stream;  /**   * 表头   */  private Map<String,String> fields;  /**   * 数据源model所有字段map   */  private static Map<String, Field> fieldMap = new HashMap<>();  public CSV(HttpServletResponse response,Map<String,String> fields,String fileName,Class<?> clz) throws IOException{    if(response == null || fields == null || fileName == null || clz == null)      throw new IllegalArgumentException();    getFieldMap(clz,fieldMap);    this.stream = response.getOutputStream();    this.fields = fields;    response.setContentType("application/octet-stream;charset=GBK");    response.setHeader("Content-Disposition", "attachment;fileName="+ fileName);    //写表头,生成指定名字的文件,返回客户端    StringBuilder hb = new StringBuilder();    for(Entry<String, String> e : fields.entrySet())      hb.append(e.getValue()+",");    stream.write(hb.substring(0, hb.length() - 1).getBytes("GBK"));    stream.flush();  }  /**   * 往表格中插入记录   */  public void write(List<Object> data) throws IllegalArgumentException, IllegalAccessException, IOException{    for(Object o : data){      StringBuilder sb = new StringBuilder();      sb.append("/n");      for(String field : fields.keySet()){        Field f = fieldMap.get(field);        f.setAccessible(true);        Object value = f.get(o);        if(value == null || StringUtils.isBlank(value.toString())){          sb.append(" ,");        } else if (f.getType() == Date.class) {          sb.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value) + ",");        } else if (f.getType() == DateTime.class) {          sb.append(((DateTime)value).toString("yyyy-MM-dd HH:mm:ss") + ",");        } else {          String tmp = value.toString();          if(tmp.contains(","))            tmp = tmp.replace(",", "/",/"");          sb.append(value.toString() + ",");        }      }      stream.write(sb.substring(0, sb.length() - 1).getBytes("GBK"));      stream.flush();    }  }  public void close() throws IOException{    stream.close();  }  private static <T extends Object> void getFieldMap(Class<T> clz, Map<String, Field> result) {    for (Field field : clz.getDeclaredFields()) {      result.put(field.getName(), field);    }    if (clz.getSuperclass() != null) {      getFieldMap(clz.getSuperclass(), result);    }  }}

web开发中常见的准备Excel数据需要从数据库查询数据,或者跨系统调用接口查询数据,耗费大量时间,因此未及时向浏览器返回数据,导致504超时。

本工具使用ServletOutputStream分段的往浏览器flush数据。调用方式:先new CSV(),传入指定参数,不断的调用wirte()方法往浏览器写入数据,最后调用close方法关闭流。

本工具导出的文件格式为.csv文件,windows office工具默认编码为ASCI,wps会匹配各种编码,libreOffice calc可以指定编码,故此设置编码为GBK,兼容三种Excel软件,也可根据自身需求设置编码。

本工具只处理了CSV中”,”的转码,对于双引号并未处理。

希望本文能够对遇到此问题的朋友能有所帮助


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表