java接口导出csv

news2024/12/24 20:23:59

1、背景介绍

项目中需要导出数据质检结果,本来使用Excel,但是质检结果数据行数过多,导致用hutool报错,因此转为导出csv格式数据。

2、参考文档

https://blog.csdn.net/ityqing/article/details/127879556
工程环境:springboot 2.2.x

3、实现

controller

    @ApiOperation("导出质检结果csv")
    @GetMapping("/export/csv/{datasetId}")
    public void exportCsv( @PathVariable String datasetId,
                            HttpServletResponse response) {
        CheckDataParamVO checkDataParamVO = new CheckDataParamVO();
        checkDataParamVO.setDatasetId(datasetId);
        checkDataService.exportCsv(checkDataParamVO, response);
    }

service

 /**
     * 导出csv格式质检结果
     *
     * @param checkDataVO
     * @param response
     */
    @Override
    public void exportCsv(CheckDataParamVO checkDataVO, HttpServletResponse response) {
        List<CheckResultVO> res = getCheckResultAll(checkDataVO);
        String fileName = "质检结果表" + DateTime.now().getTime();
        writeCsv(response, fileName, res);
    }

    /**
     * CSV文件列分隔符
     */
    private static final String CSV_COLUMN_SEPARATOR = ",";
    /**
     * CSV文件行分隔符
     */
    private static final String CSV_ROW_SEPARATOR = System.lineSeparator();

    private static final List<String> titleName = Arrays.asList("序号", "异常类型", "图层名", "要素主键");

    /**
     * @param response 响应流
     * @param fileName 文件名称
     * @param dataList 数据源
     */
    private void writeCsv(HttpServletResponse response, String fileName, List<CheckResultVO> dataList) {
        OutputStream out = null;
        try {
            StringBuffer buf = new StringBuffer();
            out = response.getOutputStream();
            String lastFileName = fileName + ".csv";
            response.setContentType("application/msexcel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(lastFileName, "UTF-8"));

            // 组装表头
            for (String title : titleName) {
                buf.append(title).append(CSV_COLUMN_SEPARATOR);
            }
            buf.append(CSV_ROW_SEPARATOR);

            //组装行数据
            dataList.forEach(data -> {
                buf.append(Optional.ofNullable(data.getSid()).orElse(0)).append(CSV_COLUMN_SEPARATOR);
                buf.append(Optional.ofNullable(data.getCheckType()).orElse("")).append(CSV_COLUMN_SEPARATOR);
                buf.append(Optional.ofNullable(data.getSubname()).orElse("")).append(CSV_COLUMN_SEPARATOR);
                buf.append(Optional.ofNullable(data.getFid()).orElse("")).append(CSV_COLUMN_SEPARATOR);
                buf.append(CSV_ROW_SEPARATOR);
            });

            //添加bom,不加Excel打开中文会乱码
            out.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            out.write(buf.toString().getBytes("UTF-8"));
        } catch (Exception e) {
            log.error("导出CSV异常", e);
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    log.error("导出CSV异常", e);
                }
            }
        }
    }

4、测试结果

可用
在这里插入图片描述
在这里插入图片描述

5、总结

以上是不使用第三方组件实现导出csv文件。测试成功。

6、补充

参考文章
https://blog.csdn.net/ityqing/article/details/127879556

6.1、bug

提到了一个中文乱码的bug
Excel 在读取 csv 的时候是通过读取文件头上的 bom 来识别编码的,这导致如果我们生成 csv 文件的平台输出无 bom 头编码的 csv 文件(例如 utf-8 ,在标准中默认是可以没有 bom 头的),Excel 只能自动按照默认编码读取,不一致就会出现乱码问题了。

6.2、解决:

写入的时候加上: out.write(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF });

6.3、其他方式

参考文章用了两种方法,另一种是引入第三方组件CSVWriter
pom.xml文件增加依赖

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.5.2</version>
</dependency>

java代码如下,自己没测。只是抄过来

/**
* @param response 响应流
* @param fileName 文件名称
* @param dataList  数据源
*/
private void writeCsv2(HttpServletResponse response, String fileName, List<TaskAplusExpire> dataList) {
    String lastFileName = fileName + ".csv";
    response.setContentType("application/msexcel;charset=UTF-8");
    try {
        response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(lastFileName, "UTF-8"));
        PrintWriter out = response.getWriter();
        // 手动加上BOM标识
        out.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));
        
        // 设置显示的顺序,数据源对象属性列表
        String[] columnMapping = { "pmid", "phone", "sendDate", "code", "message" };
       
        ColumnPositionMappingStrategy<TaskAplusExpire> mapper =
            new ColumnPositionMappingStrategy<TaskAplusExpire>();

        //数据源类型
        mapper.setType(TaskAplusExpire.class);
        mapper.setColumnMapping(columnMapping);

        // 写表头
        CSVWriter csvWriter = new CSVWriter(response.getWriter(), CSVWriter.DEFAULT_SEPARATOR,
                                            CSVWriter.NO_QUOTE_CHARACTER);
        String[] header = { "Pmid","Phone","Send Date","Code","Message"};
        csvWriter.writeNext(header);

        StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(out)
            .withMappingStrategy(mapper)
            .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
            .withSeparator(CSVWriter.DEFAULT_SEPARATOR)
            .withEscapechar('\\').build();
        beanToCsv.write(dataList);
        csvWriter.close();
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }catch (CsvDataTypeMismatchException e) {
        e.printStackTrace();
    } catch (CsvRequiredFieldEmptyException e) {
        e.printStackTrace();
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Clould 网关 - Gateway

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; Gateway网关-网关作用介绍&#xff08;P35&#xff09; Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2…

The coming up production issues

Introduction Ladies and gentlemen, give it up for the wonderful world of software production ! Now, I know that what youre thinking. "Software production!?" That sounds exciting, well, let me tell you, its a rollercoaster(过山车、剧烈起伏的事物…

【第六讲---非线性优化】

优化与优化库 优化问题 &#x1f449;优化问题组成 优化对象目标函数/损失函数/评价函数约束条件 &#x1f449;分类 可以分为凸优化和非凸优化 什么是凸优化呢&#xff1f; 目标函数是凸的&#xff08;有单一极值点称为是凸的&#xff09;不等式约束是凸的所在的空间是凸…

容器和云原生(二):Docker容器化技术

目录 Docker容器的使用 Docker容器关键技术 Namespace Cgroups UnionFS Docker容器的使用 首先直观地了解docker如何安装使用&#xff0c;并快速启动mysql服务的&#xff0c;启动时候绑定主机上的3306端口&#xff0c;查找mysql容器的ip&#xff0c;使用mysql -h contain…

【脚踢数据结构】图(纯享版)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的…

Pytest和Unittest测试框架的区别?

如何区分这两者&#xff0c;很简单unittest作为官方的测试框架&#xff0c;在测试方面更加基础&#xff0c;并且可以再次基础上进行二次开发&#xff0c;同时在用法上格式会更加复杂&#xff1b;而pytest框架作为第三方框架&#xff0c;方便的地方就在于使用更加灵活&#xff0…

Python Django 模型概述与应用

今天来为大家介绍 Django 框架的模型部分&#xff0c;模型是真实数据的简单明确的描述&#xff0c;它包含了储存的数据所必要的字段和行为&#xff0c;Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型&#xff0c;然后其它的杂七杂八代码你都不用关心&#xff0c;…

龙迅LT9711 2PORT MIPI或者LVDS转TYPE-C

LT9711 1.描述&#xff1a; Lontium LT9711是双端口MIPI/LVDS到DP1.2转换器&#xff0c;内部有c型替代模式开关和PD控制器。MIPI DSI/CSI输入具有可配置的单端口或双端口&#xff0c;具有1个时钟通道&#xff0c;1个~4个数据通道&#xff0c;最大运行2Gbps/通道&#xff0c;可…

2023 年值得关注的 8 个最佳免费开发者工具

开发者工具对开发人员的重要性不言而喻&#xff0c;保持最新工具的更新可以显著提高你的工作效率并简化您的工作流程。随着技术的快速发展&#xff0c;新的开发工具不断被引入市场。今天&#xff0c;我们将分享 2023 年你值得关注的最新开发者工具。 1.Plaky Plaky 是一种基于…

JVM——JDK 监控和故障处理工具总结

文章目录 JDK 命令行工具jps:查看所有 Java 进程jstat: 监视虚拟机各种运行状态信息 jinfo: 实时地查看和调整虚拟机各项参数jmap:生成堆转储快照**jhat**: 分析 heapdump 文件**jstack** :生成虚拟机当前时刻的线程快照 JDK 可视化分析工具JConsole:Java 监视与管理控制台连接…

司徒理财:8.17黄金反弹遇阻,1900现价空!

黄金趋势下跌&#xff0c;现在反弹遇阻&#xff0c;继续空&#xff01;除非行情强势站上1907位置&#xff0c;否则还是空头下跌走势&#xff0c;反弹遇阻直接空&#xff01;      黄金从走势上看&#xff0c;一直阴跌&#xff0c;并且在昨日加速下行&#xff01;现在黄金受…

ubuntu18.04从0到1在ros上跑yolo5

ubuntu篇---ubuntu20.04安装cuda和cudnn_ubuntu安装cudann_心惠天意的博客-CSDN博客操作系统环境&#xff1a;Ubuntu 20.041. 安装N卡驱动首先我们需要添加源&#xff0c;sudo add-apt-repository ppa:graphics-drivers/ppasudo apt update然后检查可以安装的驱动版本&#xff…

华为将收取蜂窝物联网专利费,或将影响LPWAN市场发展

近日&#xff0c;华为正式公布了其4G和5G手机、Wi-Fi6设备和物联网产品的专利许可费率&#xff0c;其中包含了长距离通信技术蜂窝物联网。作为蜂窝物联网技术的先驱&#xff0c;华为是LTE Category NB (NB-IoT)、LTE Category M和其他4G物联网标准的主要贡献者。 在NB-IoT领域…

『论文精读』Data-efficient image Transformers(DeiT)论文解读

『论文精读』Data-efficient image Transformers(DeiT)论文解读 文章目录 一. DeiT简介二. 知识蒸馏(knowledge distillation)2.1. KLDivloss2.2. 蒸馏温度 τ \tau τ2.3. distillation in transformer 三. better hyperparameter四. data augmentation五. label smoothing参…

随机微分方程

应用随机过程|第7章 随机微分方程 见知乎&#xff1a;https://zhuanlan.zhihu.com/p/348366892?utm_sourceqq&utm_mediumsocial&utm_oi1315073218793488384

2023年4大收银系统软件排名(真实测评)

现在满大街的各种服装店、便利店、百货店、母婴店...... 每天都要处理大量的订单。 使用传统的人工开单记账&#xff0c;效率低下、客户体验差、而且容易出错&#xff0c;需要耗费很多时间来回对账&#xff1b; 聪明的零售店老板都已经开始使用收银系统软件&#xff0c;通过手…

线程同步条件变量

为何要线程同步 在线程互斥中外面解决了多线程访问共享资源所会造成的问题。 这篇文章主要是解决当多线程互斥后引发的新的问题&#xff1a;线程饥饿的问题。 什么是线程饥饿&#xff1f;互斥导致了多线程对临界区访问只能改变为串行&#xff0c;这样访问临界资源的代码只能…

手把手教你Element Plus前端导出Excel表格

目录 需求背景&#xff1a; 项目环境&#xff1a; 最终效果&#xff1a; 具体实现&#xff1a; 1、下载第三方依赖包&#xff1a; pnpm下载命令&#xff1a; npm下载命令&#xff1a; 2、查看是否下载成功&#xff1a; 3、引入需要使用的页面js中 4、编写导出表格函数…

【0基础入门Python笔记】一、python 之基础语法、基础数据类型、复合数据类型及基本操作

一、python 之基础语法、基础数据类型、复合数据类型及基本操作 基础语法规则基础数据类型数字类型&#xff08;Numbers&#xff09;字符串类型&#xff08;String&#xff09;布尔类型&#xff08;Boolean&#xff09; 复合数据类型List&#xff08;列表&#xff09;Tuple&…

【傅里叶级数与傅里叶变换】数学推导——2、[Part2:T = 2 π的周期函数的傅里叶级数展开] 及 [Part3:周期为2L的函数展开]

文章内容来自DR_CAN关于傅里叶变换的视频&#xff0c;本篇文章提供了一些基础知识点&#xff0c;比如三角函数常用的导数、三角函数换算公式等。 文章全部链接&#xff1a; 基础知识点 Part1&#xff1a;三角函数系的正交性 Part2&#xff1a;T2π的周期函数的傅里叶级数展开 P…