json/excel文件上传下载工具方法汇总

news2025/1/11 17:03:52

文章目录

  • 浏览器下载json文件
  • 浏览器下载excel文件【Workbook】
  • 浏览器导入json文件【ObjectMapper】
  • 浏览器导入excel文件【Workbook】
  • ResourceLoader读取类路径下单个json
  • ResourceLoader读取类路径下所有json文件

浏览器下载json文件

    @Operation(summary = "设备模型导出(带分组)")
    @PostMapping("/export")
    public void exportWithGroup(HttpServletRequest request, HttpServletResponse response) {
        var user = SecurityUtils.getCurrentUser();
        bizTypeService.exportWithGroup(request, response, user);
    }
    
     @Override
    public void exportWithGroup(HttpServletRequest request, HttpServletResponse response, SecurityUser user) {
        // 1. 导出的数据
        ExportDto exportDto = new ExportDto();
        exportDto.setTypes(types);
        exportDto.setGroups(groups);
        // 2. 下载
        PrintWriter writer = null;
        try {
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("content-disposition", "download;filename*=utf-8''" + URLEncoder.encode("device_model_type.json", "UTF-8"));
            writer = response.getWriter();
            writer.write(JacksonUtils.writeValueAsString(exportDto)); // 转成string
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            writer.close();
        }
    }

浏览器下载excel文件【Workbook】

详见ExcelUtils
在这里插入图片描述

     @Override
    public void exportRunningRecords(
  HttpServletRequest request, HttpServletResponse response) {
        // 1.  查询数据     
        List<RunningRecordsDto> data = resultDto.getItems();
        // 2. 导出数据
        List<String> headers = new ArrayList<>();
        headers.add("设备名称");
        headers.add("设备编号");
        headers.add("所属模型");
        headers.add("安装位置");
        headers.add("服务范围");
        headers.add("运行次数");
        headers.add("运行时长");
        List<List<Object>> dataList = new ArrayList<>();
        for (RunningRecordsDto item : data) {
            List<Object> list = new ArrayList<>();
            list.add(item.getName());
            list.add(item.getCode());
            list.add(item.getTypeName());
            list.add(item.getLocationName());
            list.add(item.getServiceArea());
            list.add(item.getCounts());
            list.add(item.getDuration());
            dataList.add(list);
        }
        try {
        // 最后一个参数说明
        // false: 普通excel文件,无任何格式
        // true: excel文件第一行为黄色背景,最后一列字体为红色
            ExcelUtils.generateCreateExcel(headers, dataList, "设备运行记录.xlsx", request, response, true);
        } catch (Exception e) {
            log.error("设备运行记录导出异常", e);
        }
    }
public class ExcelUtils {
    /**
     * 导出最精简的excel.
     *
     * @param headers       (不是必填) excel头列 比如: 姓名  年龄  性别 ..
     * @param datas         (必填) 数据列(请确保和列的顺序保持一致)
     * @param fileName      生成excel的文件名称,如果不传则默认为随机生成
     * @param request       HttpServletRequest
     * @param response      HttpServletResponse
     * @param isCustomStyle 是否自定义样式
     * @throws IOException io异常
     */
    public static void generateCreateExcel(List<String> headers, List<List<Object>> datas, String fileName,
                                           HttpServletRequest request, HttpServletResponse response, Boolean isCustomStyle) throws Exception {
        Workbook workbook = generateWorkBook(headers, datas, isCustomStyle);
        // 文件名处理一下
        //设置编码
        fileName = new String(((StringUtils.isBlank(fileName) ? UUID.randomUUID().toString() : fileName) + "."
                + XSSFWorkbookType.XLSX.getExtension()).getBytes("UTF-8"), "ISO-8859-1");

        String userAgent = request.getHeader("User-Agent");
        if (userAgent.toUpperCase().contains("MSIE") || userAgent.toUpperCase().contains("RV:11")) {
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.displayName());
        } else {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        response.reset(); // 清空response
        response.setContentType(HttpHeaderEnum.FILE_DOWNLOAD_XLSL.getValue());
        response.setHeader("content-disposition", "attachment;filename=" + fileName);
        response.setCharacterEncoding("UTF-8");
        // 文件流输出
        try {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new IOException("could not write to response. cause: ", e);
        } finally {
            if (workbook != null) {
                workbook.close();
            }
        }
    }

    /**
     * 生成一个workbook.
     *
     * @param headers       (不是必填) excel头列 比如: 姓名  年龄  性别 ..
     * @param data          数据列(请确保和列的顺序保持一致)
     * @param isCustomStyle 是否自定义样式
     * @return workbook对象
     */
    public static Workbook generateWorkBook(List<String> headers, List<List<Object>> data, Boolean isCustomStyle) {
        XSSFWorkbook book = null;
        // 先创建一发book,并建一个sheet
        book = new XSSFWorkbook();
        XSSFSheet sheet = book.createSheet();
        CellStyle cellStyle1 = book.createCellStyle();
        CellStyle cellStyle2 = book.createCellStyle();
        if (isCustomStyle) {
            // 设置第一行背景颜色为黄色
            cellStyle1.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            cellStyle1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            // 设置最后一列字体为红色
            Font font = book.createFont();
            font.setColor(IndexedColors.RED.getIndex());
            cellStyle2.setFont(font);
            cellStyle2.setAlignment(HorizontalAlignment.LEFT);
            cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
        }
        // 设置自适应列宽
        List<Integer> maxCalls = getMaxCall(headers, data);
        for (int i = 0, j = maxCalls.size(); i < j; i++) {
            // 最大列宽设置
            if (maxCalls.get(i) > 30) {
                sheet.setColumnWidth(i, 30 * 256);
            } else {
                sheet.setColumnWidth(i, maxCalls.get(i) * 256);
            }
        }

        // 是否有头,如果有则先把表头建好
        if (CollectionUtils.isNotEmpty(headers)) {
            // 创建第一行,表头行
            XSSFRow titleRow = sheet.createRow(0);
            XSSFCell titleCell = null;
            XSSFRichTextString titleText = null;
            // 把表头放到第一个行里面
            for (int i = 0; i < headers.size(); i++) {
                titleCell = titleRow.createCell(i);
                // 给创建的单元格里面设值
                titleText = new XSSFRichTextString(headers.get(i));
                titleCell.setCellValue(titleText);
                if (isCustomStyle) {
                    titleRow.getCell(i).setCellStyle(cellStyle1);
                }
            }
        }
        // 处理内容
        if (CollectionUtils.isNotEmpty(data)) {
            // 如果有列表头则row重1开始。否则重0开始
            int dataRowIdx = CollectionUtils.isNotEmpty(headers) ? 1 : 0;
            XSSFRow dataRow = null;
            XSSFCell dataCell = null;
            List<Object> dataList = null;
            // 开始处理行和单元格
            for (int i = 0; i < data.size(); i++) {
                // 创建内容的行
                dataRow = sheet.createRow(i + dataRowIdx);
                dataList = data.get(i);
                // 将内容放到对应的行中
                for (int j = 0; j < dataList.size(); j++) {
                    // 有多少个内容就有多少个单元格
                    dataCell = dataRow.createCell(j);
                    // 设值单元格的值
                    setValue(book, sheet, dataCell, dataList.get(j));
                }
            }
        }
        if (isCustomStyle) {
            int lastColumnIndex = headers.size() - 1;
            for (int i = 0; i <= sheet.getLastRowNum(); i++) {
                XSSFRow row = sheet.getRow(i);
                if (row != null) {
                    XSSFCell cell = row.getCell(lastColumnIndex);
                    if (cell != null) {
                        cell.setCellStyle(cellStyle2);
                    }
                }
            }
        }
        return book;
    }

浏览器导入json文件【ObjectMapper】

   
    @Operation(summary = "设备模型导入(带分组)")
    @PostMapping("/import")
    public ApiResultDto<BizTypeImportResDto> importWithGroup(MultipartFile file) {
        var user = SecurityUtils.getCurrentUser();
        return bizTypeService.importWithGroup(file, user);
    }

	@Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResultDto<BizTypeImportResDto> importWithGroup(MultipartFile file, SecurityUser user) {
        // 1. 读取文件内容
        ObjectMapper objectMapper = new ObjectMapper();
        ExportModelDto exportModelDto = null;
        try {
            exportModelDto = objectMapper.readValue(file.getInputStream(), ExportModelDto.class);
        } catch (IOException e) {
            return PagingResultDto.failed(ApiErrorCode.DATA_CORRUPTION, "json数据格式不正确");
        }
   }

浏览器导入excel文件【Workbook】

	 @Operation(summary = "批量新增-导入excel")
    @PostMapping("/batchAdd")
    public ApiResultDto<?> batchAdd(MultipartFile file) {
        SecurityUser user = SecurityUtils.getCurrentUser();
        return locationService.batchAdd(file, user);
    }

	// 具体实现
	@Transactional(rollbackFor = Exception.class)
    public ApiResultDto<?> batchAdd(MultipartFile file, SecurityUser user) {
        UUID projectId = SecurityUtils.getCurrentUser().getProjectId();
        // 1. EXCEL文件校验
        Workbook workbook;
        try {
            String originalFilename = file.getOriginalFilename();
            if (StringUtils.isBlank(originalFilename)) {
                return ApiResultDto.failed(ApiErrorCode.VALID_FAILED, "文件名称有误");
            }
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            if (StringUtils.equals(ModelConstants.EXCEL_POSTFIX, suffix)) {
                workbook = new XSSFWorkbook(file.getInputStream());
            } else if (StringUtils.equals(ModelConstants.EXCEL_POSTFIX_XLS, suffix)) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else {
                return ApiResultDto.failed(ApiErrorCode.BAD_REQUEST, "文件格式错误,支持xls和xlsx格式文件");
            }
        } catch (Exception e) {
            log.error("errMsg", e);
            return ApiResultDto.failed(ApiErrorCode.BUSINESS_FAILURE, "文件读取失败");
        }
        // 2. 获取EXCEL文件内容
        Sheet sheet = workbook.getSheetAt(workbook.getActiveSheetIndex());
        List<LocationDto> dtos = new ArrayList<>();
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            final String type = ExcelUtils.getStringCellValue(workbook, row.getCell(0));
            String bName = ExcelUtils.getStringCellValue(workbook, row.getCell(1));
            String bSerialNum = ExcelUtils.getStringCellValue(workbook, row.getCell(2));
            String fName = ExcelUtils.getStringCellValue(workbook, row.getCell(3));
            String fSerialNum = ExcelUtils.getStringCellValue(workbook, row.getCell(4));      
            LocationDto dto = new LocationDto();
            dto.setRemark(remark);
            dto.setSort(StringUtils.isNotBlank(sort) ? Integer.valueOf(sort) : null);
            dto.setArea(Objects.nonNull(area) ? Double.valueOf(area) : null);
            dtos.add(dto);
        }
        // 3. 具体业务
        return ApiResultDto.success();
    }

ResourceLoader读取类路径下单个json

@Slf4j
@Component
public class ProjectDataBaseInitTask implements ApplicationRunner {

   /**
    * 资源加载器.
    */
   @Autowired
   private ResourceLoader resourceLoader;

   @Override
   public void run(ApplicationArguments args) {
       // 1. 读取json文件
       InitDbDataDto initDbData = getInitDbDataFromPath("classpath:init/init_property.json");
       if (Objects.isNull(initDbData)) {
           return;
       }
   }

   /**
    * 读取json文件.
    *
    * @param path 文件路径.
    * @return 初始化数据类.
    */
   private InitDbDataDto getInitDbDataFromPath(String path) {
       if (StringUtils.isEmpty(path)) {
           return null;
       }
       Resource resource = resourceLoader.getResource(path);
       if (!resource.exists()) {
           log.error("初始化数据不存在");
           return null;
       }
       InitDbDataDto initDbData = null;
       try {
           InputStream inputStream = resource.getInputStream();
            // 判断当前可读取的字节数
            if (inputStream.available() == 0) {
                continue;
            }
           ObjectMapper objectMapper = new ObjectMapper();
           initDbData = objectMapper.readValue(inputStream, InitDbDataDto.class);
       } catch (IOException e) {
           log.error("读取json文件错误");
           throw new RuntimeException(e);
       }
       return initDbData;
   }
}

ResourceLoader读取类路径下所有json文件

	/**
     * 读取classpath:init文件夹下所有json文件.
     *
     * @param path 文件路径.
     * @return 初始化数据类.
     */
    private List<InitDbDataDto> getInitDataFromPath(String path) {
        List<InitDbDataDto> initDbDataDtos = new ArrayList<>();
        // 1. 读取类路径指定文件夹下所有文件
        PathMatchingResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
        Resource[] resources;
        try {
            resources = resourceLoader.getResources(path);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (Objects.isNull(resources)) {
            return initDbDataDtos;
        }
        // 2. 解析数据ObjectMapper
        for (Resource resource : resources) {
            InitDbDataDto initDbData = null;
            try {
                InputStream inputStream = resource.getInputStream();
                 // 判断当前可读取的字节数
                if (inputStream.available() == 0) {
                    continue;
                }
                ObjectMapper objectMapper = new ObjectMapper();
                initDbData = objectMapper.readValue(inputStream, InitDbDataDto.class);
                initDbDataDtos.add(initDbData);
            } catch (IOException e) {
                log.error("读取json文件错误");
                throw new RuntimeException(e);
            }
        }
        return initDbDataDtos;
    }
    List<InitDbDataDto> initDbDatas = getInitDataFromPath("classpath:init/*");

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

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

相关文章

【Vue】自动导入组件

1. 下载插件 npm install unplugin-vue-components 2. 修改vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import Components from unplugin-vue-components/vite // 按需加载自定义组件/…

鲜花门店小程序开发流程:详细教程,让你轻松掌握

想要开发一款专属于自己鲜花门店的小程序吗&#xff1f;不知道从何开始&#xff1f;别担心&#xff0c;本文将为你提供详细的开发流程&#xff0c;帮助你轻松掌握。 1. 注册登录乔拓云网并进入操作后台 首先&#xff0c;你需要注册并登录乔拓云网&#xff0c;然后进入操作后台…

系统开发与运行知识

系统开发与运行知识 导航 文章目录 系统开发与运行知识导航一、软件工程二、软件生命周期三、开发模型四、开发方法五、需求分析结构化分析 六、数据流图分层数据流图的画法设计注意事项 七、数据字典数据字典的内容 八、系统设计九、结构化设计常用工具十、面向对象十一、UML…

集合的创建

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python中的集合同数学中的集合概念类似&#xff0c;也是用于保存不重复元素的。它有可变集合&#xff08;set&#xff09;和不可变集合&#xff08;f…

Vue3实战笔记(34)—完美的菜单组件封装

文章目录 前言多层菜单封装总结 前言 之前简单的封装了一下菜单组件&#xff0c;数据都是写死的&#xff0c;多层嵌套没有支持&#xff0c;学完了组件传值&#xff0c;计算属性就可以继续完善了。 多层菜单封装 先看下数据结构&#xff1a; {"id":"1",&q…

K210 数字识别 笔记

一、烧写固件 连接k210开发板&#xff0c;点开烧录固件工具&#xff0c;选中固件&#xff0c;并下载 二、模型训练 网站&#xff1a;MaixHub 1、上传文件 2、开始标记数据 添加9个标签&#xff0c;命名为1~9&#xff0c;按键盘w开始标记&#xff0c;键盘D可以下一张图片&…

Redis学习篇2:Redis在Spring中的应用

本文继上文开始讲述了Redis在IDEA中如何应用以及集成进入spring开发环境&#xff0c;以及如何使用Redis客户端。上一个文章&#xff1a;Redis学习篇1&#xff1a;初识Redishttps://blog.csdn.net/jialuosi/article/details/139057088 一、Redis在java中的客户端 二、SpringDat…

Spring Boot中@Value加载配置的替代者:@ConfigurationProperties

Value注解Spring Boot开发者都已经熟悉了&#xff0c;通过该注解&#xff0c;我们可以快速的把配置信息加载到Spring的Bean中。 例如&#xff1a;在application.yml中添加了一个配置如下&#xff1a; 我想在service中获取name&#xff0c;通过value注解方式实现&#xff0c;代…

【JVM精通之路】垃圾回收-三色标记算法

首先预期你已经基本了解垃圾回收的相关知识&#xff0c;包括新生代垃圾回收器&#xff0c;老年代垃圾回收器&#xff0c;以及他们的算法&#xff0c;可达性分析等等。 先想象一个场景 最开始黑色节点是GC-Roots的根节点&#xff0c;这些对象有这样的特点因此被选为垃圾回收的根…

你什么时候感觉学明白Java了?

学是学不明白Java的&#xff0c;要学明白Java&#xff0c;一定只能在工作以后。 1 在学习阶段&#xff0c;哪怕是借鉴别人的学习路线&#xff0c;其实依然会学很多不必要的技能&#xff0c;比如jsp&#xff0c;swing&#xff0c;或者多线程&#xff0c;或者设计模式。 2 或者…

你对仲裁裁决不服怎么办?我教你四个狠招!

你对仲裁裁决不服怎么办&#xff1f;我教你四个狠招&#xff01; 这个标题是什么意思呢&#xff1f;也就是说&#xff0c;当你&#xff08;或用人单位&#xff09;向劳动仲裁委提出仲裁申请后&#xff0c;但劳动仲裁结果没有维护你的权益&#xff0c;或者你不满意&#xff0c;…

【Nginx <三>⭐️⭐️⭐️】Nginx 负载均衡使用

目录 &#x1f44b;前言 &#x1f440;一、 负载均衡概述 &#x1f331;二、项目模拟 2.1 环境准备 2.2 启动多个服务器 2.3 配置 Nginx 2.4 测试配置 &#x1f49e;️三、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;前不久开始学习了 Nginx 的使用&#xff0c;在…

如何克隆非默认分支

直接git clone下来的我们知道是默认分支&#xff0c;那如何克隆其他分支呢&#xff1a; 比如这个&#xff0c;我们想克隆AdvNet。 我们可以在本地文件夹打开Git Bash 依次输入&#xff1a; git clone --branch AdvNet https://github.com/wgcban/SemiCD.git cd SemiCD git b…

Monaco-Editor在Vue中使用(实现代码编辑与diff代码比较)--类似vscode代码编辑器

Monaco-Editor 是一个由 Microsoft 开发的 Web 代码编辑器&#xff0c;它是 Visual Studio Code 的浏览器版本。在 Vue 项目中集成 Monaco-Editor 可以提供代码编辑、语法高亮、智能提示等功能 效果&#xff1a; 1、安装使用&#xff0c;最好安装指定版本&#xff0c;我是 vue…

力扣算法之1070. 产品销售分析 III

力扣传送门 题解 选出每个售出过的产品 第一年 销售的 产品 id、年份、数量 和 价格&#xff0c;很明显就是个排序问题 我的解 SELECT product_id,year as first_year,quantity,price FROM ( SELECT sale_id,RANK() OVER(PARTITION BY product_id ORDER BY [year] asc ) A…

Matlab-熵权法

文章目录 熵权法一、模型简介二、例题1. 数据标准化2.指标的熵值和变异程度3.权重与评分4.代码实现 熵权法 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多…

Docker安装Nginx 并实现通过nginx部署静态网址

Docker镜像就是一个只读的模板&#xff0c;可以用来创建Docker容器。 例如&#xff1a;一个镜像可以包含一个完整的centos操作系统环境&#xff0c;里面仅安装了mysql、nginx等或用户需要的其他应用程序。 Docker提供了一个非常简单的机制来创建镜像或者更新现有的镜像&#…

OpenHarmony Camera源码分析

一、简介 当前&#xff0c;开源在科技进步和产业发展中发挥着越来越重要的作用&#xff0c;OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&#xff09;赋予了开发者孕育创新的种子&#xff0c;也为数字化产业发展开辟了一片土壤。深开鸿是开源的坚定践行者&#xff0c…

开源VS闭源:谁将引领AI大模型的新时代?

一、引言 随着人工智能技术的飞速发展&#xff0c;AI大模型已成为推动这一浪潮的核心动力。在AI大模型的发展过程中&#xff0c;开源与闭源两种不同的发展路径一直备受关注。本文将深入探讨这两种路径的优劣势&#xff0c;分析它们对AI大模型发展的影响&#xff0c;并预测谁将…