springboot将数据库的查询结果导出为文件

项目中有这样的需求,将数据库中的查询结果导出成json格式文件,于是我总结了三种实现方式:

  1. 直接使用response输出流实现,并使用fastjson作为序列化工具:
public void exportTestHisDetail(JSONObject condition , HttpServletResponse response) {

		// 使用mybatisPlus查询数据结果
		String key= condition.getString("key");
		LambdaQueryWrapper<TestHisDetail> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TestHisDetail::getTestBatchKey,key);
		// list是从数据库中查询出的结果集
		List<TestHisDetail> list = detail.selectList(queryWrapper);
		
		// 导出内容到浏览器
		try (
			// 获取响应输出流
			OutputStream outputStream = response.getOutputStream();){
			// 设置响应头
			response.setContentType("application/json");
			response.setHeader("Content-Disposition", "attachment; filename=\"export.json\"");
			// 将查询到的结果序列化为json格式
			String jsonString = JSON.toJSONString(list, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
					SerializerFeature.WriteDateUseDateFormat);
			// 将序列化的json数据集写入到输出流中
			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
			// 推送输出流结果到浏览器
			outputStream.flush();
		}catch (Exception e){
			log.error("导出文件失败"+e);
		}

	}

在上面的代码中,我们同样使用 JdbcTemplate 执行 SQL 查询,获取结果集。然后,我们设置 HTTP 响应的 Content-Type 为 application/json,以及 Content-Disposition 头,将文件名设置为 export.json。

接下来,我们使用 fastjson 将结果集转换为 JSON 字符串,并设置了一些序列化特性,例如 PrettyFormat(格式化输出)、WriteMapNullValue(输出 null 值的属性)、WriteDateUseDateFormat(按照指定的日期格式输出日期)。最后,我们将 JSON 字符串写入到输出流中,并关闭输出流。

需要注意的是,fastjson 可能存在一些安全问题,因此建议使用时选择较新版本的 fastjson,并及时更新以修复已知漏洞。另外,需要根据具体的业务需求和查询结果的特点,设置合适的序列化特性,以避免导出的文件过大或格式不正确等问题。

  1. 使用Spring Boot自带的Jackson库来实现:

    public void exportTestHisDetail(JSONObject condition,HttpServletResponse response){
    
       // 使用mybatisPlus查询数据结果
		String key= condition.getString("key");
		LambdaQueryWrapper<TestHisDetail> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TestHisDetail::getTestBatchKey,key);
		// list是从数据库中查询出的结果集
		List<TestHisDetail> list = detail.selectList(queryWrapper);
        // 设置响应头
        response.setContentType("application/json");
        response.setHeader("Content-Disposition", "attachment; filename=\"export.json\"");
        try(
        	// 获取响应输出流
			OutputStream outputStream = response.getOutputStream();
			){
			// 使用springboot的Jackson库进行序列化
			 ObjectMapper mapper = new ObjectMapper();
        	 mapper.writerWithDefaultPrettyPrinter().writeValue(outputStream , list);
			}catch (Exception e){
			log.error("导出文件失败"+e);
		} 
    }

在上面的代码中,我们首先执行数据库查询,获取结果集。然后,我们设置HTTP响应的Content-Type为application/json,以及Content-Disposition头,将文件名设置为export.json。接下来,我们使用ObjectMapper将结果集写入到输出流中,并使用writerWithDefaultPrettyPrinter方法设置缩进格式,使输出结果更易读。最后,我们关闭输出流。

需要注意的是,如果导出的数据量比较大,可能会导致内存占用过高,从而导致性能问题。此时,可以考虑使用分页查询或者流式查询来解决这个问题。另外,还需要注意设置合适的Content-Type和Content-Disposition头,以确保浏览器能够正确地识别导出的文件类型和文件名。

  1. 使用 ResponseEntity 响应对象来实现该功能:

在controller层以ResponseEntity作为返回值,返回给浏览器端

// 为了精简代码此方法就直接抛出异常,不再进行抓取
@GetMapping("/export")
public ResponseEntity<Resource> exportTestHisDetail() throws IOException {

   // TODO: 查询数据库并导出数据为 JSON 字符串,此处可参考上面的查询案例
   String jsonData = ...;

   // 构造 ResponseEntity 对象,设置响应头和响应体
    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=export.json");
    // 设置响应体为json格式
    MediaType mediaType = MediaType.APPLICATION_JSON;
    ResponseEntity<String> responseEntity = ResponseEntity.ok()
            .headers(headers)
            .contentType(mediaType)
            .body(jsonData);
    return responseEntity;

在上述代码中,我们首先查询数据库并将查询结果导出为一个 JSON 字符串。然后,我们使用 ResponseEntity 对象来构造响应,将导出的 JSON 字符串设置为响应体,并设置响应头中的 Content-Disposition 为 “attachment; filename=export.json”,表示将响应体作为附件下载,并将下载的文件命名为 export.json。

最后,我们使用 ResponseEntity.ok() 方法来设置响应状态码为 200 OK,并返回 ResponseEntity 对象。这样,在调用该 RESTful API 接口时,服务器会将导出的 JSON 数据作为一个名为 export.json 的附件返回给客户端,客户端就可以将其下载保存到本地磁盘中。

以下是文件下载中的几个细节:

  1. 当使用 Fastjson 进行序列化时,可以通过设置不同的序列化特性参数来控制序列化的行为和结果:
String json = JSON.toJSONString(object, 
// 控制是否将输出的 JSON 字符串格式化为可读性更好的形式
SerializerFeature.PrettyFormat,
// 控制是否将 Map 中的空值输出为 null 值
SerializerFeature.WriteMapNullValue,
// 控制是否将 null 值的字符串输出为空字符串
SerializerFeature.WriteNullStringAsEmpty,
//  控制是否将 null 值的数字类型输出为 0
SerializerFeature.WriteNullNumberAsZero,
// 控制是否禁用循环引用检测
SerializerFeature.DisableCircularReferenceDetect,
// 控制是否将枚举类型输出为字符串
SerializerFeature.WriteEnumUsingToString
);
  1. 在 HTTP 协议中,Content-Disposition 是一个响应头部字段,用于指示如何处理响应体的内容。具体而言,它可以用来告诉浏览器将响应体作为下载文件保存到本地,还是直接在浏览器中展示内容。

常用的 Content-Disposition 值有两个:

inline:将响应体作为普通的网页内容直接在浏览器中展示;
attachment:将响应体作为附件下载到本地。
当设置 Content-Disposition 为 attachment 时,可以使用 filename 参数指定下载文件的文件名,例如:

Content-Disposition: attachment; filename="export.json"

这样就会在下载对话框中显示一个默认文件名为 “export.json” 的下载链接,用户点击下载后会将服务器返回的响应体保存为一个名为 “export.json” 的文件。

需要注意的是,由于 Content-Disposition 是一个响应头部字段,因此只能由服务器端设置。客户端无法直接修改响应头部字段。

  1. 在 Spring 框架中,ResponseEntity 是一个用于表示 HTTP 响应的对象,它封装了响应状态码、响应头和响应体等信息。通常在 Spring MVC 或 Spring WebFlux 应用程序中用于返回 HTTP 响应。

ResponseEntity 的构造函数接受一个泛型类型参数,用于指定响应体的类型。例如,可以使用

ResponseEntity<String> responseEntity = ResponseEntity.ok().body("Hello, world!");

来构造一个包含字符串 “Hello, world!” 的 HTTP 响应,其中的 ok() 方法表示响应状态码为 200 OK。

在实际使用中,我们可以使用 ResponseEntity 对象来返回各种类型的响应,包括文本、HTML、JSON、XML 等格式的数据。同时,我们还可以设置响应头、响应状态码等属性,以便更好地控制 HTTP 响应的行为。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
可以通过以下步骤将数据库数据导出成txt文件,并保存至桌面: 1. 在Spring Boot项目中添加依赖: ```xml <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> ``` 2. 编写导出数据的代码 ```java import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class ExportData implements CommandLineRunner { @Autowired private UserRepository userRepository; @Override public void run(String... args) throws Exception { List<User> users = userRepository.findAll(); if (users != null && !users.isEmpty()) { String fileName = "users.txt"; File file = new File(System.getProperty("user.home") + "/Desktop/" + fileName); FileWriter writer = new FileWriter(file); for (User user : users) { writer.write(user.getId() + "," + user.getName() + "," + user.getEmail() + "\n"); } writer.close(); System.out.println("Data exported successfully to: " + file.getAbsolutePath()); } else { System.out.println("No data found to export!"); } } } ``` 3. 运行Spring Boot应用程序,导出数据 当应用程序启动时,`CommandLineRunner`接口的`run`方法将被调用,该方法将从数据库中检索用户列表,并将其写入桌面上的`users.txt`文件中。如果没有找到数据,则输出“无数据可导出!”的消息。 导出文件将保存在桌面上,您可以根据需要更改文件名和路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王钧石的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值