GET请求或POST请求导出Excel

1.GET请求和POST请求导出的区别
  • 在有些场景中导出前端页面上表格中的数据是通过条件进行精确导出的。

  • 使用GET请求方式

    GET请求方式是比较简单的,简单的处理前端只需要通过一个a标签就能实现导出或下载。

    但是使用GET请求的需要考虑:

    检索条件多不多,其次就是如果检索条件拼接在请求URL上会不会超过请求URL的最大长度。如果请求URL的长度超过浏览器的限制长度,浏览器将会将请求自动截断。

    GET请求适用于导出所有数据或者是有个把检索条件并且检索条件长度不是特别长的。总之简单导出使用GET请求还是很香的!

  • 各浏览器对请求URL长度的限制:
    GET请求或POST请求导出Excel_第1张图片

  • 或者是考虑采用POST请求来处理

    POST请求的方式做导出比较的麻烦,需要前后端配合来使用,为了确保更好的用户体验(在用户点击导出或下载后,可以看到文件的下载进度),通过流的方式来实现导出或下载。

    后端将处理好的数据存储在Excel表格中,读取Excel表格,以流的方式响应给前端;

    前端通过Blob类型接收,通过window.URL.createObjectURL()创建源路径,使用document文档对象创建一个a标签;为a标签添加href属性和值(值就是源路径),为a标签设置download属性和值(值就是被下载的文件名),将指定a标签节点加到document.body的末尾,最后为a标签设置一个自触发的点击事件。

    POST请求最适用于检索条件多的场景

2.Excel操作工具:Alibaba EasyExcel

对Excel相关的操作我使用的是阿里巴巴提供的一个工具包EaxyExcel,如果你对EasyExcel并没有接触可以通过以下文章进行了解

EasyExcel全面教程快速上手

alibaba easyexcel 官方教程,附详细说明、例子、源码

史上最全的Excel导入导出之easyexcel

3.导出演示Demo
1.准备
  • 技术栈:SpringBoot、mysql、mybatis-plus、EasyExcel、lombok、swagger2
  • sql语句
create table t_brand
(
    bid   int auto_increment comment '主键ID'
        primary key,
    bname varchar(255) not null comment '品牌名称'
)
    comment '品牌表';

create table t_category
(
    cid   int auto_increment comment '主键ID'
        primary key,
    cname varchar(50) null comment '分类名称'
)
    comment '分类表';

create table t_products
(
    id          int auto_increment comment '主键ID'
        primary key,
    pname       varchar(255) not null comment '商品名称',
    price       double       not null comment '商品价格',
    flag        char         not null comment '是否上架标记为:1表示上架、0表示下架',
    category_id int          not null comment '分类ID',
    brand_id    int          not null,
    inventory   int          not null
)
    comment '商品表';

INSERT INTO t_brand (bid, bname) VALUES(1, '华为
');
INSERT INTO t_brand (bid, bname) VALUES(2, '苹果');
INSERT INTO t_brand (bid, bname) VALUES(3, '小米');
INSERT INTO t_brand (bid, bname) VALUES(4, '三星');
INSERT INTO t_brand (bid, bname) VALUES(5, '坚果');
INSERT INTO t_brand (bid, bname) VALUES(6, '1+');
INSERT INTO t_brand (bid, bname) VALUES(7, '锤子');

INSERT INTO t_category (cid, cname) VALUES(1, '手机');

INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(1, '华为P0 Pro', 8999.0, '0', 1, 1, 10000);
INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(2, '华为P1 Pro', 8999.0, '0', 1, 1, 10000);
INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(3, '华为P2 Pro', 8999.0, '0', 1, 1, 10000);
INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(4, '苹果P3 Pro', 8999.0, '0', 1, 1, 10000);
INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(5, '苹果P4 Pro', 8999.0, '0', 1, 1, 10000);
INSERT INTO t_products (id, pname, price, flag, category_id, brand_id, inventory) VALUES(6, '苹果P5 Pro', 8999.0, '0', 1, 1, 10000);
  • 需求
    • 1.导出所有品牌信息
    • 2.导出商品品牌是手机、商品名中包含华为、价格是在1000-9000之间的所有商品
2.实现
  • 引入相关依赖

<dependency>
  <groupId>mysqlgroupId>
  <artifactId>mysql-connector-javaartifactId>
  <version>5.1.48version>
dependency>


<dependency>
  <groupId>com.baomidougroupId>
  <artifactId>mybatis-plus-boot-starterartifactId>
  <version>3.3.2version>
dependency>


<dependency>
  <groupId>com.alibabagroupId>
  <artifactId>druid-spring-boot-starterartifactId>
  <version>1.1.9version>
dependency>


<dependency>
  <groupId>com.alibabagroupId>
  <artifactId>easyexcelartifactId>
  <version>2.1.3version>
dependency>


<dependency>
  <groupId>io.springfoxgroupId>
  <artifactId>springfox-swagger2artifactId>
  <version>2.9.2version>
dependency>
<dependency>
  <groupId>io.springfoxgroupId>
  <artifactId>springfox-swagger-uiartifactId>
  <version>2.9.2version>
dependency>

<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starter-aopartifactId>
dependency>

<dependency>
  <groupId>org.projectlombokgroupId>
  <artifactId>lombokartifactId>
  <optional>trueoptional>
dependency>

<dependency>
  <groupId>com.alibabagroupId>
  <artifactId>fastjsonartifactId>
  <version>1.2.61version>
dependency>



  • po
package com.scholartang.model.po;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ContentRowHeight(15)//内容的行高
@HeadRowHeight(20)//表头的行高
@ColumnWidth(25)//宽度
@TableName("t_brand")
@ApiModel(description = "品牌表",value = "Brand")
public class Brand extends Model<Brand>{
    /**
    * 主键ID
    */
    @ApiModelProperty(value="主键ID")
    @TableId(value = "bid",type = IdType.AUTO)
    @ExcelProperty("编号") //设置表头信息
    private Integer bid;

    /**
    * 品牌名称
    */
    @ApiModelProperty(value="品牌名称")
    @TableField("bname")
    @ExcelProperty("名称")
    private String bname;
}
package com.scholartang.model.po;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@ApiModel(description = "分类表",value = "Category")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@TableName("t_category")
public class Category extends Model<Category> {
    /**
    * 主键ID
    */
    @ApiModelProperty(value="主键ID")
    @TableId(value = "cid",type = IdType.AUTO)
    private Integer cid;

    /**
    * 分类名称
    */
    @ApiModelProperty(value="分类名称")
    @TableField("cname")
    private String cname;
}

package com.scholartang.model.po;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ApiModel(description = "商品类",value = "Products")
@ContentRowHeight(10)
@HeadRowHeight(20)
@ColumnWidth(25)
@TableName("t_products")
public class Products extends Model<Products> {

    @ExcelIgnore
    @ApiModelProperty(value="主键ID")
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    @ExcelProperty("商品名称")
    @ApiModelProperty(value="商品名称")
    @TableField("pname")
    private String pname;

    @ExcelProperty("商品价格")
    @ApiModelProperty(value="商品价格")
    @TableField("price")
    private Double price;

    @ExcelProperty("状态")
    @ApiModelProperty(value="是否上架标记为:1表示上架、0表示下架")
    @TableField("flag")
    private String flag;

    @ExcelIgnore
    @ApiModelProperty(value="分类ID")
    @TableField(value = "category_id")
    private Integer categoryId;

    @ExcelIgnore
    @ApiModelProperty(value="品牌ID")
    @TableField("brand_id")
    private Integer brandId;

    @ExcelProperty("库存")
    @ApiModelProperty(value="库存")
    @TableField("inventory")
    private Integer inventory;

    @ExcelProperty("分类")
    @ApiModelProperty("非表字段:分类名称")
    @TableField(exist = false)
    private String categoryName;

    @ExcelProperty("品牌")
    @ApiModelProperty("非表字段:品牌名称")
    @TableField(exist = false)
    private String brandName;
}

  • 1.导出所有品牌信息

因为只是单纯的导出没有任何的条件,所以使用GET请求处理起来会跟好一些

后端

//controller
@GetMapping("/exportBrand")
public void exportBrand(HttpServletResponse response) throws IOException {
  service.exportBrand(response);
}

//service
void exportBrand(HttpServletResponse response) throws IOException;

//serviceImpl
@Override
public void exportBrand(HttpServletResponse response) throws IOException {
  List<Brand> brandList = brandMapper.selectList(null);
  response.setContentType("application/vnd.ms-excel");
  response.setCharacterEncoding("utf-8");
  // 这里URLEncoder.encode可以防止中文乱码
  String fileName = URLEncoder.encode("测试", "UTF-8");
  response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
  EasyExcel.write(response.getOutputStream(),Brand.class).sheet("data").doWrite(brandList);
}

前端

<el-button type="primary">
  <a style="text-decoration: none;color: aliceblue" href="http://localhost:8087/brand/exportBrand">导出品牌信息a>
el-button>
  • 2.导出商品品牌是手机、商品名中包含华为、价格是在1000-9000之间的所有商品

导出数据的检索条件比较多这里采用POST请求的方式来导出Excel文件

后端

//controller
@PostMapping("/filterExportProducts")
public void filterExportProducts(@RequestBody QueryProductsVo queryProductsVo, HttpServletRequest request, HttpServletResponse response) throws Exception{
service.filterExportProducts(queryProductsVo,request,response);
}


//service
void filterExportProducts(QueryProductsVo queryProductsVo,HttpServletRequest request, HttpServletResponse response) throws Exception;


//serviceImpl
@Override
public void filterExportProducts(QueryProductsVo queryProductsVo, HttpServletRequest request, HttpServletResponse response) throws Exception {
  //根据条件查询出对应的商品信息
  List<Products> productsList = productsMapper.conditionQueryProducts(queryProductsVo.getPname(), queryProductsVo.getBrandId(), queryProductsVo.getCategoryId(), queryProductsVo.getLowestPrice(), queryProductsVo.getHighestPrice());
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
EasyExcel.write(response.getOutputStream(),Products.class).sheet("data").doWrite(productsList); 
}


//ProductsMapper
@Results({
  @Result(column = "category_id", property = "categoryId"),
  @Result(column = "brand_id", property = "brandId"),
  @Result(column = "category_id",one = @One(select = "com.scholartang.mapper.CategoryMapper.selectCnameByCid"),property = "categoryName"),
  @Result(column = "brand_id",one = @One(select = "com.scholartang.mapper.BrandMapper.selectBnameByBid"),property = "brandName")
})
@Select("")
List<Products> conditionQueryProducts(@Param("pname") String pname,@Param("brandId") Integer brandId,@Param("categoryId") Integer categoryId,@Param("lowestPrice") Double lowestPrice,@Param("highestPrice") Double highestPrice);

//CategoryMapper
@Select("select cname from t_category where cid = #{categoryId}")
String selectCnameByCid(@Param("categoryId") Integer categoryId);

//BrandMapper
@Select("select bname from t_brand where bid = #{brandId}")
String selectBnameByBid(@Param("brandId") Integer brandId);
















前端

<el-button type="primary" @click="exportProducts">导出商品信息el-button>

<script>
  import axios from 'axios';
  export default {
    data() {
      return {
        pageQuery: {
          pname: "",
          categoryId: "",
          brandId: "",
          lowestPrice: "",
          highestPrice: "",
          page: 1,
          rows: 10
        }
      }
    },
    methods: {
      exportProducts() {
        axios.post("/products/filterExportProducts", this.pageQuery,{responseType: "blob"}).then(res => {
          const content = res.data;
          const blob = new Blob([content],{type: "application/vnd.ms-excel;charset=utf-8"})
          const fileName = '商品信息.xlsx'
          const url = window.URL.createObjectURL(blob);
          const link = document.createElement('a')
          link.href = url;
          link.setAttribute('download',fileName)
          document.body.appendChild(link);
          link.click();
        })
      }
    }
  }
script>    


你可能感兴趣的:(EasyExcel,java,excel)