当前位置: 首页 > news >正文

Java使用csv导出多字段大数据文件(无需写实体映射,自动遍历)

  1. csv工具类CsvUtils
    此处使用LinkedHashMap链表哈希表,实现键值中值为空时仍存在数据以及保证顺序与sql顺序一致。
package com.xxx.xxx.utils;import lombok.val;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;public class CsvUtils {/*** CSV文件列分隔符*/private static final String CSV_COLUMN_SEPARATOR = ",";/*** CSV文件行分隔符*/private static final String CSV_ROW_SEPARATOR = "\r\n";/*** @param dataList 集合数据* @param titles   表头部数据* @param keys     表内容的键值* @param os       输出流*/public static void doExport(List<LinkedHashMap<String, String>> dataList, String titles, String keys, OutputStream os)throws Exception {// 保证线程安全StringBuffer buf = new StringBuffer();String[] titleArr = null;String[] keyArr = null;titleArr = titles.split(",");keyArr = keys.split(",");// 组装表头for (String title : titleArr) {buf.append(title).append(CSV_COLUMN_SEPARATOR);}buf.append(CSV_ROW_SEPARATOR);// 组装数据if (!CollectionUtils.isEmpty(dataList)) {for (Map<String, String> data : dataList) {for (String key : keyArr) {buf.append(CsvUtils.handleFormatValue(data.get(key))).append(CSV_COLUMN_SEPARATOR);}buf.append(CSV_ROW_SEPARATOR);}}// 写出响应os.write(buf.toString().getBytes("GBK"));os.flush();}/*** 设置Header 辅助函数, 可用可不用** @param fileName* @param response* @throws UnsupportedEncodingException*/public static void responseSetProperties(String fileName, HttpServletResponse response)throws UnsupportedEncodingException {// 设置文件后缀SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String fn = fileName + sdf.format(new Date()) + ".csv";// 读取字符编码String utf = "UTF-8";// 设置响应response.setContentType("application/ms-txt.numberformat:@");response.setCharacterEncoding(utf);response.setHeader("Pragma", "public");response.setHeader("Cache-Control", "max-age=30");response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fn, utf));}// 处理数据private static String handleFormatValue(Object data) {if (data == null) {return "";}String val = data.toString();// 如果数据中含有 " 则在 "外层再包一层 ""if (val.contains("\"") ){val=val.replace("\"", "\"\"");}// 如果数据中含有 , 则在 , 外层再包一层 ""if (val.contains(",")) {val = "\""+val+"\"";} else {// \t 是为了处理字符串的日期类型数据导出显示异常val = "\t" + val;}return val;}
}
  1. 修改ymlmybatis配置 根据实际情况修改call-setters-on-nullstrue即可
mybatis-plus:# 扫描mapper.xml文件mapper-locations: classpath:mapper/*/*.xml,classpath:mapper/system_settings/*/*/*.xml# 扫描实体类typeAliasesPackage: com.sun.system.entity# 主键类型global-config:#配置逻辑删除字段为1是删除logic-delete-value: 1#配置逻辑删除字段为0是未删除logic-not-delete-value: 0#主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";id-type: 1# Sequence序列接口实现类配置key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"field-strategy: 0#驼峰下划线转换db-column-underline: true#刷新mapper 调试神器refresh-mapper: true#数据库大写下划线转换#capital-mode: true#自定义SQL注入器configuration:# 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射map-underscore-to-camel-case: true# 全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 truecache-enabled: true#懒加载#aggressive-lazy-loading: true#NONE:不启用自动映射 PARTIAL:只对非嵌套的 resultMap 进行自动映射 FULL:对所有的 resultMap 都进行自动映射#auto-mapping-behavior: partial#NONE:不做任何处理 (默认值设置)WARNING:以日志的形式打印相关警告信息 FAILING:当作映射失败处理,并抛出异常和详细信息#auto-mapping-unknown-column-behavior: none#如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段call-setters-on-nulls: true# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImplmybatis:configuration:call-setters-on-nulls: true
  1. controller查询后导出
    @RequestMapping("generateCSV")// 解决跨域问题@CrossOriginpublic void generateHqmsCSV(HttpServletResponse response,@RequestBody Map<String,Object> data) throws Exception {ServletOutputStream outputStream = response.getOutputStream();String keys = "";List<LinkedHashMap<String, String>> dataList = xxxMapper.getxxx(data);// 遍历Map获取所有的键和值for (Map.Entry<String, String> entry : dataList.get(0).entrySet()) {keys += entry.getKey()+",";}keys = removeTrailingComma(keys);CsvUtils.doExport(dataList,keys,keys,outputStream);}/*** 检查字符串是否以逗号结尾,如果是,则去掉最后一个字符(即逗号)* @param str* @return*/public static String removeTrailingComma(String str) {if (str.endsWith(",")) {return str.substring(0, str.length() - 1);}return str;}
  1. 前台调用(需要先跨域后使用,详见跨域问题解决(后端Java+前端Vue2))
  2. END
http://www.lryc.cn/news/346838.html

相关文章:

  • Redis 本机无法访问
  • 【论文笔记】Training language models to follow instructions with human feedback B部分
  • stm32——OLED篇
  • 重卡生产流程的可视化管理与优化
  • 软考-软件工程
  • Agent AI智能体:未来社会的角色、发展路径与挑战
  • Vue 3.x组件生命周期
  • onnx模型截取部分
  • 中职智慧校园建设内容规划
  • GitLab CI/CD的原理及应用详解(一)
  • Python混淆矩阵用例
  • 【负载均衡式在线OJ项目day6】源文件路由功能及文件版题库构建
  • 841.钥匙和房间
  • 【OceanBase 系列】—— 什么是冻结和转储
  • 智慧园区能耗管控系统,3D可视化开发都需要哪些技术栈?
  • Spring之推断构造方法源码解析
  • 【计算机网络】计算机网络的定义和分类
  • 天机学堂—学习辅助功能(含场景问答和作业)
  • Stable Diffusion AI绘画
  • linux性能监控之sar
  • react框架对Excel文件进行上传和导出
  • 【前端】-【前端文件操作与文件上传】-【前端接受后端传输文件指南】
  • 【IC前端虚拟项目】验证环境env与base_teat思路与编写
  • 使用Remix部署智能合约到币安链(Remix的操作介绍 币安链合约的部署) 点赞收藏哦
  • 为什么Redis6.0引入了多线程
  • 速盾:高防ip和高防cdn有什么相同点?
  • 设计模式之拦截过滤器模式
  • 【联通支付注册/登录安全分析报告】
  • c++ - 在循环中使用迭代器删除 unordered_set 中的元素
  • 深入了解哈希映射(HashMap)