Java csv文件上传下载中的相关转换

目录

  • 一. 需求
  • 二. `List<Entity>`转`List<List<String>>`
    • 2.1 实体类
    • 2.2 转换
  • 三. 上传csv文件转`List<Map>`
    • 3.1 csv文件
    • 3.2 前台
    • 3.3 实体类
    • 3.4 转换
    • 3.5 效果


一. 需求

🤔项目中遇到了两个需求

1.查询数据库,得到List<Entity>这种数据类型,然后需要将List<Entity>转换为List<List<String>>之后,调用共通方法下载CSV数据。
2.前台上传csv文件到后台,后台需要将csv文件处理为List<Map>这种数据类型,然后遍历List插入数据库。


二. List<Entity>List<List<String>>

2.1 实体类

  • 在类的内部定义了一个@excludeCSV注解,用于标识指定的属性不进行转换
import lombok.Builder;
import lombok.Data;import java.lang.annotation.*;@Data
@Builder
public class Category {@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface excludeCSV {}private String id;@excludeCSVprivate String password;private String parentValid;private String parentId;private String name;private String updateTime;
}

2.2 转换

  • 要点就是反射,因为实体类的属性都是private,所以需要使用 .setAccessible(true) 使其强制可访问。
  • 因为不确定List中的类型是什么,因此使用 List<?>
  • 部分属性不需要转换,使用自定义注解@excludeCSV来标识。
import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.lang.reflect.Field;
import java.util.*;@Controller
@RequestMapping("/test33")
public class Test33Controller implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {// 模拟从数据库查询到的List<Entity>数据List<Category> categoryList = List.of(Category.builder().id("1").name("张三").parentId("11").updateTime("2023").build(),Category.builder().id("2").name("李四").parentId("22").updateTime("2024").build(),Category.builder().id("3").name("王五").parentId("33").updateTime("2025").build());// 进行转换List<List<String>> csvDataList = this.handleData(categoryList);System.out.println(csvDataList);/*[[1, , 11, 张三, 2023], [2, , 22, 李四, 2024], [3, , 33, 王五, 2025]]*/}public List<List<String>> handleData(List<?> dataList) throws IllegalAccessException {List<List<String>> strList = new ArrayList<>();List<String> valueList;Field[] fields;for (Object data : dataList) {valueList = new ArrayList<>();// 获取所有修饰符的属性fields = data.getClass().getDeclaredFields();for (Field field : fields) {// 如果包含指定的注解,则该csv项目不处理if (field.isAnnotationPresent(Category.excludeCSV.class)) {continue;}// 使该属性强制可访问field.setAccessible(true);// 获取属性值valueList.add(Optional.ofNullable(field.get(data)).orElse("").toString());}strList.add(valueList);}return strList;}
}

三. 上传csv文件转List<Map>

3.1 csv文件

"ID","姓名","年龄","地址"
"1","张三",18,"山东省"
"2","李四",19,"山西省"

3.2 前台

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><input type="file" id="csv" accept=".csv" /><button id="btn">上传文件</button>
</body>
<script type="text/javascript" th:src="@{/js/public/jquery-3.6.0.min.js}"></script>
<script>$(function() {bindEvent();});function bindEvent() {$("#btn").click(() => {const formData = new FormData();formData.append("multipartFile", $("#csv").get(0).files[0]);$.ajax({url: `/test33/fileUpload`,type: 'POST',processData: false,contentType: false,data: formData,success: function (data, status, xhr) {console.log(data);}});});}
</script>
</html>

3.3 实体类

import lombok.Data;
import org.springframework.web.multipart.MultipartFile;@Data
public class Test33Form {// 用来接收前台传入的csv文件private MultipartFile multipartFile;
}

3.4 转换

  • 因为上传的不是json数据,因此使用Form接收的时候不需要加@RequestBody
  • 后台接收到的文件类型为MultipartFile,需要将其转换为File后读取其中的内容。
  • 可以使用File.createTempFile()创建临时文件,使用完之后需要删除,否则占用磁盘空间。
  • 可以使用Files.readAllLines()读取全部的文本文件数据。
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.*;@Controller
@RequestMapping("/test33")
public class Test33Controller {private static final String CHARSET = "UTF-8";// CSV列的字段名映射private Map<Integer, String> csvColumnMap = new HashMap<>(){{put(0, "id");put(1, "name");put(2, "age");put(3, "address");}};@PostMapping("/fileUpload")public ResponseEntity<Void> fileUpload(Test33Form form) throws IOException {// 获取前台上传的csvMultipartFile multipartFile = form.getMultipartFile();// 将csv文件临时存储到本地String originalFilename = multipartFile.getOriginalFilename();// 获取文件名以及文件名的后缀String fileName = StringUtils.stripFilenameExtension(originalFilename);String filenameExtension = StringUtils.getFilenameExtension(originalFilename);// 创建临时文件File tempFile = File.createTempFile(fileName, filenameExtension);multipartFile.transferTo(tempFile);// 指定通过 UTF-8 编码读取CSV中的数据; 如果读取的是日语文件,通常格式为 Shift_JISList<String> csvList = Files.readAllLines(tempFile.toPath(), Charset.forName(CHARSET));// 删除csv文件中的第一行的标题csvList.remove(0);// 删除临时文件Files.delete(tempFile.toPath());List<Map<String, Object>> csvMapList = new ArrayList<>();for (String csvRow : csvList) {Map<String, Object> csvMap = new HashMap<>();List<String> csvItemList = Arrays.asList(csvRow.split(","));for (int i = 0; i < csvItemList.size(); i++) {csvMap.put(csvColumnMap.get(i), csvItemList.get(i));}csvMapList.add(csvMap);}System.out.println(csvMapList);// 响应给前台return ResponseEntity.noContent().build();}
}

3.5 效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14135.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[NISACTF 2022]checkin

[NISACTF 2022]checkin 直接给了源码&#xff0c;乍一看非常的简单&#xff0c;但是这题有坑。其实看注释颜色不一样&#xff0c;也能发现不对劲了。 贴一个payload&#xff0c;?ahahahahajitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan%E2%80%AE%E2…

【lambda函数】lambda()函数

lambda&#xff08;&#xff09; lambda&#xff08;&#xff09;语法捕捉列表mutable lambda 底层原理函数对象与lambda表达式 lambda&#xff08;&#xff09;语法 lambda表达式书写格式&#xff1a; [capture-list] (parameters) mutable -> return-type{ statement }咱…

uniapp学习之【uniapp的返回事件 onBackPress 在微信小程序中不生效的问题】

uniapp 的返回事件 onBackPress 在微信小程序中不生效的问题 场景&#xff1a;页面中点击左上角的返回按钮,监听返回操作,页面返回前执行了一些操作, uniapp 页面生命周期中有 onBackPress ,因此将操作写在了 onBackPress () 页面生命周期钩子当中, H5 测试一切正常,但是微信开…

认识文件操作与IO

文章目录 认识文件文件夹文件路径文件分类 文件操作File类构造方法常用方法 字节流IOInputStream常用方法 FileInputStream构造方法FileInputStream实例 OutputStream方法 FileOutputStream 字符流IO 认识文件 我们平时所说的文件指的是存在硬盘上的文件&#xff0c;我们平时的…

webpack5搭建与基本概念

webpack基础构建 新建文件夹进入文件夹查看是否安装node&#xff0c;命令&#xff1a;node-v创建package.json文件&#xff0c;命令&#xff1a;npm init -y安装webpack和webpack-cli&#xff0c;&#xff08;命令自动创建出package-lock.json文件和node_modules文件夹&#x…

天猫数据分析工具(天猫实时数据)

后疫情时代&#xff0c;聚会、聚餐与送礼热度上涨&#xff0c;酒类产品既作为送礼首选又作为佐餐饮品的热门选手也受此影响迎来消费小高峰。在此背景下&#xff0c;白酒市场也开始复苏并不断加快速度。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年1月份至4月…

AI Chat 设计模式:5. 策略模式

本文是该系列的第五篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的旁白。 问题列表 Q.1 我想学习一下策略模式A.1Q.2 你先给我简单讲解一下吧A.2Q.3 你举得这个电商平台例子不错&#xf…

RabbitMQ的可视化管理页面简介

模块 描述 Overview 概览 Connections 查看连接情况 Channels 信道(通过)情况 Exchanges 交换机(路由)情况,默认四类七个 Queues 消息队列情况 Admin …

TLS、SSL、CA 证书、公钥、私钥

1. HTTP 的问题 HTTP 协议是超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff09;的缩写&#xff0c;它是从 WEB 服务器传输超文本标记语言 HTML 到本地浏览器的传送协议。HTTP 设计之初是为了提供一种发布和接收 HTML 页面的方法&#xff0c;时至今日&#x…

javaWeb中的Ajax_待后期增加

前言&#xff1a; Ajax是一种在JavaWeb开发中常用的技术&#xff0c;通过它可以实现异步通信和动态加载数据&#xff0c;提升用户体验。 正文&#xff1a; 首先我们得明白异步通信&#xff0c;客户端发出请求后可以继续执行其他操作 由于原生的Ajax过于复杂 so&#xff1a; …

DFS解决N-皇后问题

题目&#xff1a; n−皇后问题是指将 n个皇后放在 nn的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包…

论文学习——U-Net: Convolutional Networks for Biomedical Image Segmentation

UNet的特点 采用端到端的结构&#xff0c;通过FCN&#xff08;最后一层仍然是通过卷积完成&#xff09;&#xff0c;最后输出图像。通过编码&#xff08;下采样&#xff09;-解码&#xff08;上采样&#xff09;形成一个“U”型结构。每次下采样时&#xff0c;先进行两次卷积&…