Spring Boot中前端通过请求接口下载后端存放的Excel模板

导出工具类

package com.yutu.garden.utils;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** @ClassName: ExcelUtils* @Description: Excel相关操作* @Author* @Date 2022/4/11* @Version 1.0*/
@Component
public class ExcelUtils {@Resourceprivate  ResourceLoader resourceLoader;private static Logger log = LoggerFactory.getLogger(ExcelUtils.class);static{System.setProperty("java.awt.headless", "true");}/*** 设置表头* @param sheet sheet* @param str 表头数据* @param startNum 开始行* @param height 高度* @param style 样式*/public static void setTitle(HSSFSheet sheet, String[] str,int startNum,Short height,HSSFCellStyle style,Integer[] widths,int width) {try {HSSFRow row = sheet.createRow(startNum);if(ObjectUtils.isEmpty(height)){height = (short)(20*20);}row.setHeight(height);//创建表头名称HSSFCell cell;for (int j = 0; j < str.length; j++) {cell = row.createCell(j);//设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度if(ObjectUtils.isNotEmpty(widths) && ObjectUtils.isNotEmpty(widths[j]) ){sheet.setColumnWidth(j, widths[j]);}else{sheet.autoSizeColumn(j);int colWidth = sheet.getColumnWidth(j) * width / 10;
//					if (colWidth > 255) {
//						colWidth = 255;
//					}sheet.setColumnWidth(j, colWidth);}cell.setCellValue(str[j]);cell.setCellStyle(style);}} catch (Exception e) {e.printStackTrace();}}public static void setTitle(HSSFSheet sheet, List<String> str,int startNum,Short height,HSSFCellStyle style,Integer[] widths) {try {HSSFRow row = sheet.createRow(startNum);if(ObjectUtils.isEmpty(height)){height = (short)(20*20);}row.setHeight(height);//创建表头名称HSSFCell cell;for (int j = 0; j < str.size(); j++) {cell = row.createCell(j);//设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度if(ObjectUtils.isNotEmpty(widths) && ObjectUtils.isNotEmpty(widths[j]) ){sheet.setColumnWidth(j, widths[j]);}else{sheet.autoSizeColumn(j);sheet.setColumnWidth(j, sheet.getColumnWidth(j) * 30 / 10);}cell.setCellValue(str.get(j));cell.setCellStyle(style);}} catch (Exception e) {e.printStackTrace();}}/*** 方法名:setData* 功能:表格赋值*/public static void setData(HSSFSheet sheet, List<Object[]> data,int startNum,HSSFCellStyle style) {try{int rowNum = startNum+1;for (int i = 0; i < data.size(); i++) {HSSFRow row = sheet.createRow(rowNum);for (int j = 0; j < data.get(i).length; j++) {HSSFCell cell = row.createCell(j);if(ObjectUtils.isEmpty(data.get(i)[j])){cell.setCellValue("");}else{cell.setCellValue(data.get(i)[j].toString());}cell.setCellStyle(style);}rowNum++;}}catch (Exception e){e.printStackTrace();}}public static void setDataByList(HSSFSheet sheet, List<List<Object>> data,int startNum) {try{int rowNum = startNum+1;for (int i = 0; i < data.size(); i++) {HSSFRow row = sheet.createRow(rowNum);for (int j = 0; j < data.get(i).size(); j++) {if(ObjectUtils.isEmpty(data.get(i).get(j))){row.createCell(j).setCellValue("");}else{row.createCell(j).setCellValue(data.get(i).get(j).toString());}}rowNum++;}}catch (Exception e){e.printStackTrace();}}/*** 方法名:setBrowser* 功能:使用浏览器下载*/public static void setBrowser(HttpServletResponse response, HSSFWorkbook workbook, String fileName) {try {//清空response//response.reset();//设置response的HeaderString name = URLEncoder.encode(fileName, "UTF-8");//Content-disposition 的 attachment参数将文件作为附件下载//response.setHeader("Content-disposition", "attachment;filename=" + fileName+".xlsx");response.setHeader( "Content-Disposition", "attachment;filename=\"" + name + "\".xlsx;filename*=utf-8''" + name +".xlsx");OutputStream os = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");//将excel写入到输出流中workbook.write(os);os.flush();os.close();} catch (Exception e) {e.printStackTrace();}}/*** 居中* @param workbook* @return*/public static HSSFCellStyle getStyleByCENTER(HSSFWorkbook workbook,int size){//设置标题样式HSSFCellStyle style = workbook.createCellStyle();HSSFFont font = workbook.createFont();font.setBold(true);font.setFontName("宋体");font.setFontHeightInPoints((short) size);style.setFont(font);//水平居中style.setAlignment(HorizontalAlignment.CENTER);//垂直居中style.setVerticalAlignment(VerticalAlignment.CENTER);style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));return style;}/*** 带边框的样式* @param workbook workbook* @param size 字体大小* @param isText 是否正文* @return*/public static HSSFCellStyle getStyleByBorder(HSSFWorkbook workbook,int size,boolean isText){//设置标题样式HSSFCellStyle style = workbook.createCellStyle();HSSFFont font = workbook.createFont();if(!isText){font.setBold(true);}font.setFontName("宋体");font.setFontHeightInPoints((short) size);style.setFont(font);//水平居中style.setAlignment(HorizontalAlignment.CENTER);//垂直居中style.setVerticalAlignment(VerticalAlignment.CENTER);style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));//边框style.setBorderBottom(BorderStyle.THIN);style.setBorderLeft(BorderStyle.THIN);style.setBorderTop(BorderStyle.THIN);style.setBorderRight(BorderStyle.THIN);return style;}public static HSSFCellStyle getDataStyle(HSSFWorkbook workbook,int size,boolean isSetBold,HSSFColor.HSSFColorPredefined background){//设置标题样式HSSFCellStyle style = workbook.createCellStyle();HSSFFont font = workbook.createFont();font.setBold(isSetBold);font.setFontName("宋体");font.setFontHeightInPoints((short) size);style.setFont(font);if(ObjectUtils.isNotEmpty(background)){//设置填充方式style.setFillPattern(FillPatternType.SOLID_FOREGROUND);style.setFillForegroundColor(background.getIndex());}return style;}/*** 解析上传的excel, 默认只解析第一张Sheet** @param file     excel* @param startRow 数据开始行* @return List<String [ ]>* @throws IOException*/public static List<String> getExcelData(MultipartFile file, int startRow, Integer endRow){int resultSize = 0;ArrayList<String> resultData = new ArrayList<>(resultSize);try {if (!checkFile(file)) {log.error("上传的excel文件格式有问题");return resultData;}//获得Workbook工作薄对象Workbook workbook = getWorkBook(file);if (ObjectUtils.isNotEmpty(workbook)) {//获取第一张sheet工作表Sheet sheet = workbook.getSheetAt(0);if (ObjectUtils.isEmpty(sheet)) {return resultData;}// 重新初始化List结果大小resultSize = sheet.getLastRowNum() + 1;//获得当前sheet的开始行int firstRowNum = sheet.getFirstRowNum();//获得当前sheet的结束行int lastRowNum = sheet.getLastRowNum();if(ObjectUtils.isNotEmpty(endRow)){lastRowNum = endRow;}//循环除了startRow的所有行,如果要循环除第一行以外的就firstRowNum+1for (int rowNum = firstRowNum + startRow; rowNum <= lastRowNum; rowNum++) {//获得当前行Row row = sheet.getRow(rowNum);if (rowIsEmpty(row)) {break;}//获得当前行的开始列int firstCellNum = row.getFirstCellNum();//获得当前行的列数int lastCellNum = row.getLastCellNum();//String[] cells = new String[lastCellNum];StringBuilder stringBuffer = new StringBuilder();//循环当前行for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {Cell cell = row.getCell(cellNum);//cells[cellNum] = getCellValue(cell);String cellValue = getCellValue(cell);stringBuffer.append(getCellValue(cell)).append(",&");//加个&防止有答案中有,的}//resultData.add(cells);resultData.add(stringBuffer.toString());}workbook.close();}} catch (IOException e) {e.printStackTrace();}return resultData;}/*** 检查文件格式** @param file* @throws IOException*/public static boolean checkFile(MultipartFile file) throws IOException {if (null == file) {log.error("文件不存在!");return false;}//获得文件名String fileName = file.getOriginalFilename();//判断文件是否是excel文件if (ObjectUtils.isEmpty(fileName) || (!fileName.endsWith("xls") && !fileName.endsWith("xlsx"))) {log.error(fileName + "不是excel文件");return false;}return true;}/*** 获取工作簿对象** @param file* @return*/public static Workbook getWorkBook(MultipartFile file) {//获得文件名String fileName = file.getOriginalFilename();//创建Workbook工作薄对象,表示整个excelWorkbook workbook = null;try {//获取excel文件的io流InputStream is = file.getInputStream();//根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象if(ObjectUtils.isNotEmpty(fileName)){if (fileName.endsWith("xls")) {//2003workbook = new HSSFWorkbook(is);} else if (fileName.endsWith("xlsx")) {//2007 及2007以上workbook = new XSSFWorkbook(is);}}} catch (IOException e) {log.error(e.getMessage());}return workbook;}public static String getCellValue(Cell cell) {String cellValue = "";if (cell == null) {return cellValue;}switch (cell.getCellTypeEnum()) {case NUMERIC://数字cellValue = stringDateProcess(cell);break;case STRING://字符串cellValue = String.valueOf(cell.getStringCellValue());break;case BOOLEAN://BooleancellValue = String.valueOf(cell.getBooleanCellValue());break;case FORMULA://公式cellValue = String.valueOf(cell.getCellFormula());break;case BLANK://空值cellValue = "";break;case ERROR://故障cellValue = "非法字符";break;default:cellValue = "未知类型";break;}return cellValue;}public static String stringDateProcess(Cell cell) {String result = new String();if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式SimpleDateFormat sdf = null;if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {sdf = new SimpleDateFormat("HH:mm");} else {// 日期sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");}Date date = cell.getDateCellValue();result = sdf.format(date);} else if (cell.getCellStyle().getDataFormat() == 58) {// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");double value = cell.getNumericCellValue();Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);result = sdf.format(date);} else {double value = cell.getNumericCellValue();CellStyle style = cell.getCellStyle();DecimalFormat format = new DecimalFormat();String temp = style.getDataFormatString();// 单元格设置成常规if ("General".equals(temp)) {int decimalPlaces = countDecimalPlaces(value);StringBuilder pattern = new StringBuilder("#.");for (int i = 0; i < decimalPlaces; i++) {pattern.append("#");}format.applyPattern(pattern.toString());}result = format.format(value);}return result;}public static int countDecimalPlaces(double value) {String stringValue = Double.toString(value);int integerPlaces = stringValue.indexOf('.');return stringValue.length() - integerPlaces - 1;}/*** @return * @param null* @Author* @Description //TODO 判断excel的row是否全为空* @Date 2019/12/2 19:30* @Param*/public static boolean rowIsEmpty(Row row) {if (null == row) {return true;}for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {Cell cell = row.getCell(c);if (cell != null && cell.getCellTypeEnum() != CellType.BLANK) {return false;}}return true;}/*** 模板下载* @param response* @param request* @param filename* @param path* @throws IOException*/public void downloadTemplate(HttpServletResponse response, HttpServletRequest request, String filename, String path) throws IOException {InputStream inputStream = null;ServletOutputStream servletOutputStream = null;try {org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:" + path);response.setContentType("application/vnd.ms-excel");response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");response.addHeader("charset", "utf-8");response.addHeader("Pragma", "no-cache");String encodeName = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString());response.setHeader("Content-Disposition", "attachment; filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);inputStream = resource.getInputStream();servletOutputStream = response.getOutputStream();IOUtils.copy(inputStream, servletOutputStream);response.flushBuffer();} catch (Exception e) {e.printStackTrace();} finally {try {if (servletOutputStream != null) {servletOutputStream.close();}if (inputStream != null) {inputStream.close();}// jvm的垃圾回收System.gc();} catch (Exception e) {e.printStackTrace();}}}
}

控制层接口

package com.yutu.garden.controller;import com.yutu.garden.utils.ExcelUtilsWP;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@RestController
@RequestMapping("excel")
@Api(tags = "Excel模板下载")
public class ExcelTemplateController {@Resourceprivate ExcelUtilsWP excelUtils;@ApiOperation("下载苗木计划清单模板")@GetMapping("/downloadPunishTemplate")public void downloadPunishTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {String filename = "苗木计划清单模板.xlsx";String path = "template/苗木计划清单模板.xlsx";excelUtils.downloadTemplate(response,request,filename,path);}
}

Excel模板存放位置

在这里插入图片描述

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

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

相关文章

vue项目引入微信sdk: npm install weixin-js-sdk --save报错

网上查到要用淘宝的镜像 同事告知旧 域名&#xff1a;https://registry.npm.taobao.org/已经不能再使用 使用 npm config set registry http://registry.npmmirror.com

[力扣]根据前中序构造二叉树--详细解析

根据前中序遍历顺序构建一个二叉树 力扣练习链接 过程 总体框架 设preorder的左边界为pleft,右边界为pright[注意这里是闭区间能取到]同时设inorder的左边界为ileft,有边界为iright[同样也是可以取到的索引区间]我们生成每一个区间的树的头结点,然后向上返回,对于他的父亲结点…

基于ssm的轻型卡车零部件销售平台(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的轻型卡车零部件销售平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 轻型卡车零部件销售平台…

Unity类银河恶魔城学习记录12-2 p124 Character Stats UI源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI_Statslot.cs using System.Collections; using System.Collections.Gen…

Hadoop和zookeeper集群相关执行脚本(未完,持续更新中~)

1、Hadoop集群查看状态 搭建Hadoop数据集群时&#xff0c;按以下路径操作即可生成脚本 [test_1analysis01 bin]$ pwd /home/test_1/hadoop/bin [test_01analysis01 bin]$ vim jpsall #!/bin/bash for host in analysis01 analysis02 analysis03 do echo $host s…

Windows下Docker搭建Flink集群

编写docker-compose.yml 参照&#xff1a;https://github.com/docker-flink/examples/blob/master/docker-compose.yml version: "2.1" services:jobmanager:image: flink:1.14.4-scala_2.11expose:- "6123"ports:- "18081:8081"command: jobma…

防止推特Twitter账号被冻结,应该选什么代理类型IP?

在处理多个 Twitter 帐号时&#xff0c;选择合适的代理IP对于避免大规模帐户暂停至关重要。现在&#xff0c;问题出现了&#xff1a;哪种类型的代理是满足您需求的最佳选择&#xff1f;下面文章将为你具体讲解推特账号冻结原因以及重点介绍如何选择代理IP。 一、推特账号被冻结…

vue 数据埋点

最近菜鸟做项目&#xff0c;需要做简单的数据埋点&#xff0c;不是企业级的&#xff0c;反正看渡一的视频&#xff0c;企业级特别复杂&#xff0c;包括但不限于&#xff1a;错误收集、点击地方、用户行为…… 菜鸟的需求就是简单收集一下用户的ip、地址、每个界面的访问时间&a…

计算机网络-HTTP相关知识-HTTP的发展

HTTP/1.1 特点&#xff1a; 简单&#xff1a;HTTP/1.1的报文格式包括头部和主体&#xff0c;头部信息是键值对的形式&#xff0c;使得其易于理解和使用。灵活和易于扩展&#xff1a;HTTP/1.1的请求方法、URL、状态码、头字段等都可以自定义和扩展&#xff0c;使得其具有很高的…

【SpringCloud】Ribbon 负载均衡

目 录 一.负载均衡原理二.源码跟踪1. LoadBalancerIntercepor2. LoadBalancerClient3. 负载均衡策略 IRule4. 总结 三.负载均衡策略1.负载均衡策略2.自定义负载均衡策略 四.饥饿加载 在 order-service 中 添加了 LoadBalanced 注解&#xff0c;即可实现负载均衡功能&#xff0c…

Ubuntu20.04使用Neo4j导入CSV数据可视化知识图谱

1.安装JDK&#xff08; Ubuntu20.04 JDK11&#xff09; sudo apt-get install openjdk-11-jdk -y java -version which java ls -l /usr/bin/java ls -l /etc/alternatives/java ls -l /usr/lib/jvm/java-11-openjdk-amd64/bin/java确认安装路径为/usr/lib/jvm/java-11-openjd…

Flutter iOS上架指南

本文探讨了使用Flutter开发的iOS应用能否上架&#xff0c;以及上架的具体流程。苹果提供了App Store作为正式上架渠道&#xff0c;同时也有TestFlight供开发者进行内测。合规并通过审核后&#xff0c;Flutter应用可以顺利上架。但上架过程可能存在一些挑战&#xff0c;因此可能…

三星加强Bixby智能:迈向生成式AI,抗衡谷歌Gemini

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

VGA显示器驱动设计与验证

1.原理 场同步信号的单位是像素点 场同步信号的单位是一行 60的含义是每秒钟刷新60帧图像 全0表示黑色 2.1 CLK_gen.v module CLK_gen(input wire sys_clk ,input wire sys_rst_n ,output wire CLK_out ,output wire locked );parameter STATE1b0; reg [1:0] cnt; r…

非关系型数据库-----------Redis的主从复制、哨兵模式

目录 一、redis群集有三种模式 1.1主从复制、哨兵、集群的区别 1.1.1主从复制 1.1.2哨兵 1.1.3集群 二、主从复制 2.1主从复制概述 2.2主从复制的作用 ①数据冗余 ②故障恢复 ③负载均衡 ④高可用基石 2.3主从复制流程 2.4搭建redis主从复制 2.4.1环境准备 2.4…

elementui 左侧或水平导航菜单栏与main区域联动

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、elementui 实现一个固定位置的Pagination&#xff08;分页&#xff09;组件 文章目录 系列文章目录…

配置zookeeper的时候三个节点都启动了但是查询zookeeper的角色的时候显示没启动成功

场景 搭建了一个音乐平台数仓&#xff0c;一共有五个节点&#xff0c;其中三个节点配置zookeeper&#xff0c;我的操作是先把这三个节点的zookeeper全部启动&#xff0c;然后再分别查询各自zookeeper的角色。出现了一下问题&#xff1a; Error contacting service. It is proba…

【Java】:继承

目录 1.为什么需要继承 2.继承的概念 3.继承的语法 4.父类成员访问 4.1子类和父类不存在同名成员变量 1.子类和父类不存在同名成员变量 2.子类和父类成员变量同名 4.2子类中访问父类的成员方法 1.成员方法名字不同 2.成员方法名字相同 5.super关键字 6.子类构造方法 …

CTF下加载CTFtraining题库以管理员身份导入 [HCTF 2018]WarmUp,之后以参赛者身份完成解题全过程

-------------------搭建CTFd------------------------------ 给大家介绍一个本地搭建比较好用的CTF比赛平台&#xff1a;CTFD。 CTFd是一个Capture The Flag框架&#xff0c;侧重于易用性和可定制性。它提供了运行CTF所需的一切&#xff0c;并且可以使用插件和主题轻松进行自…

212 基于matlab的双稳态随机共振的算法

基于matlab的双稳态随机共振的算法&#xff0c;分析信噪比随系统参数a,b及乘性噪声和加性噪声的增益变化曲线&#xff0c;60个数据样本可供选择。程序已调通&#xff0c;可直接运行。 212 双稳态随机共振 信噪比增益变化曲线 - 小红书 (xiaohongshu.com)