Skip to content

第一部分:导出

(1)在数据库tools下创建一个名为tb_saie的

(2)导入数据库数据(sql语句)

plain
INSERT INTO `tb_sale`
(`sale_type`, `sale_info`, `sale_amount`, `sale_receive_amount`, `sale_state`, `sale_order_custom`, `sale_order_custom_phone`, `sale_address`, `sale_order_install_state`, `sale_date`)
VALUES
-- 普通售卖订单(sale_type=0)
(0, '售卖甲级防盗门1樘,款式:极简雅黑款,材质:锌合金,配备C级锁芯', 2899.00, 2899.00, 1, '李晓明', '13800138001', '北京市朝阳区建国路88号现代城5号楼1202室', 1, '2024-01-05 09:30:00'),
(0, '售卖乙级防盗门2樘,款式:经典木纹款,材质:冷轧钢板,配备超C级锁芯', 5298.00, 2649.00, 0, '王芳', '13900139002', '上海市浦东新区张江高科技园区博云路2号3栋101室', 0, '2024-01-12 14:15:00'),
(0, '售卖丙级防盗门1樘,款式:简约白漆款,材质:钢板,配备C级锁芯,含上门测量服务', 1899.00, 1899.00, 1, '张伟', '13700137003', '广州市天河区天河路385号天俊阁15楼08室', 1, '2024-01-18 10:00:00'),
(0, '售卖甲级防盗门1樘,款式:轻奢拼接款,材质:铝型材+钢板,配备指纹锁', 4599.00, 3000.00, 0, '刘敏', '13600136004', '深圳市南山区科技园科苑路8号科兴科学园B座2205室', 0, '2024-02-02 15:20:00'),
(0, '售卖乙级防盗门1樘,款式:复古雕花款,材质:冷轧钢板,配备机械锁+天地钩', 2699.00, 2699.00, 1, '陈杰', '13500135005', '杭州市西湖区文三路478号华星时代广场A座903室', 1, '2024-02-08 09:45:00'),
(0, '售卖丁级防盗门1樘,款式:基础平板款,材质:薄钢板,配备普通C级锁,用于出租房', 1299.00, 1299.00, 1, '赵娜', '13400134006', '成都市锦江区春熙路东段1号IFS国际金融中心2号楼3002室', 1, '2024-02-15 11:30:00'),
(0, '售卖甲级防盗门2樘,款式:现代磨砂款,材质:锌合金,配备智能锁(支持密码+刷卡+指纹)', 9198.00, 4599.00, 0, '黄强', '13300133007', '武汉市洪山区光谷大道70号光谷金融港A1栋801室', 0, '2024-02-22 16:40:00'),
(0, '售卖乙级防盗门1樘,款式:双色撞色款,材质:冷轧钢板,配备防撬锁芯', 2999.00, 2999.00, 1, '周丽', '13200132008', '重庆市渝中区解放碑邹容路100号时代广场C座1806室', 1, '2024-03-01 10:15:00'),
(0, '售卖丙级防盗门1樘,款式:窄边极简款,材质:钢板,配备静音锁体', 2199.00, 1000.00, 0, '吴涛', '13100131009', '西安市雁塔区高新区科技路38号林凯国际大厦12楼1201室', 0, '2024-03-07 14:50:00'),
(0, '售卖甲级防盗门1樘,款式:高端铸铝款,材质:全铸铝,配备人脸识别锁', 6899.00, 6899.00, 1, '郑敏', '13000130010', '南京市玄武区中山路18号德基广场2期15楼1503室', 1, '2024-03-14 09:20:00'),


-- 工程单订单(sale_type=1)
(1, '某小区1号楼工程单:甲级防盗门30樘,统一款式:小区标准款,材质:冷轧钢板,配备工程专用C级锁芯,含批量安装及1年售后', 86970.00, 52182.00, 0, 'XX房地产开发有限公司', '010-88888888', '北京市丰台区马家堡东路100号XX小区1号楼', 0, '2024-01-20 11:00:00'),
(1, '某办公楼装修工程单:乙级防盗门15樘,款式:商务简约款,材质:锌合金,配备智能刷卡锁,用于办公室及公共区域', 40485.00, 40485.00, 1, 'XX建筑装饰工程有限公司', '021-66666666', '上海市静安区南京西路1266号XX办公楼', 1, '2024-01-28 15:30:00'),
(1, '某学校宿舍楼工程单:丙级防盗门25樘,款式:校园安全款,材质:钢板,配备防破坏锁体,要求符合校园安全标准', 47475.00, 23737.50, 0, 'XX教育建设发展有限公司', '020-77777777', '广州市番禺区广州大学城外环西路230号XX学校宿舍楼', 0, '2024-02-10 10:45:00'),
(1, '某工业园区厂房工程单:甲级防盗门20樘,款式:工业抗造款,材质:加厚冷轧钢板,配备防水锁芯,用于厂房车间及仓库', 57980.00, 57980.00, 1, 'XX工业园区管理有限公司', '0755-99999999', '深圳市宝安区福永街道XX工业园区1-5号厂房', 1, '2024-02-18 16:10:00'),
(1, '某安置房小区工程单:丁级防盗门50樘,款式:经济实用款,材质:基础钢板,配备普通C级锁,控制成本优先', 64950.00, 32475.00, 0, 'XX安置房建设指挥部', '0571-55555555', '杭州市余杭区良渚街道XX安置房小区2-6号楼', 0, '2024-03-03 09:50:00'),
(1, '某酒店装修工程单:乙级防盗门40樘,款式:酒店轻奢款,材质:铝型材,配备感应卡锁(与酒店系统对接),含上门调试', 119960.00, 119960.00, 1, 'XX酒店管理有限公司', '027-44444444', '武汉市武昌区中北路108号XX酒店', 1, '2024-03-10 14:25:00'),
(1, '某医院门诊楼工程单:甲级防盗门18樘,款式:医疗专用款,材质:防腐蚀钢板,配备静音防撬锁,符合医疗场所防火要求', 52182.00, 31309.20, 0, 'XX医院后勤保障部', '023-33333333', '重庆市渝北区金山大道201号XX医院门诊楼', 0, '2024-03-17 10:30:00'),
(1, '某商业综合体商铺工程单:丙级防盗门35樘,款式:商铺展示款,材质:透明玻璃+钢板边框,配备遥控锁,用于商铺大门', 76965.00, 76965.00, 1, 'XX商业管理有限公司', '029-22222222', '西安市新城区解放路111号XX商业综合体1-3层商铺', 1, '2024-03-24 15:45:00'),
(1, '某别墅群工程单:甲级高端防盗门8樘,款式:别墅定制款,材质:全铸铝+实木拼接,配备人脸识别+远程控制锁', 55192.00, 27596.00, 0, 'XX别墅开发有限公司', '025-11111111', '南京市江宁区汤山街道XX别墅群A1-A8栋', 0, '2024-03-30 09:10:00'),
(1, '某养老院工程单:乙级防滑防盗门12樘,款式:养老安全款,材质:防滑钢板,配备紧急呼救锁体(与养老院警报系统联动)', 32388.00, 32388.00, 1, 'XX养老服务有限公司', '010-99999999', '北京市海淀区温泉镇XX养老院', 1, '2024-04-05 14:00:00');

(3)使用代码生成工具生成实体类以及三层架构

plain
package com.xja.application.generation;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class CodeGeneration {
 public static void main(String[] args) {
 /**
 * 先配置数据源
 */
 MySqlQuery mySqlQuery = new MySqlQuery() {
 `@Override`
 public String[] fieldCustom() {
 return new String[]{"Default"};
 }
 };

 DataSourceConfig dsc = new DataSourceConfig.Builder("jdbc:mysql://192.168.25.3:3306/tools?&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false","root","MySQL5.7#")
 .dbQuery(mySqlQuery).build();
 //通过datasourceConfig创建AutoGenerator
 AutoGenerator generator = new AutoGenerator(dsc);


 Scanner scanner = new Scanner(System.in);
 System.out.println("代码生成的绝对路径(右键项目->copy path):");
 String projectPath = scanner.next();
 System.out.println("请输入表名,多个英文逗号分隔,所有输入 all");
 String s = scanner.next();

 /**
 * 全局配置
 */
 //String projectPath = System.getProperty("user.dir"); //获取项目路径

 String filePath = projectPath + "/src/main/java"; //java下的文件路径
 GlobalConfig global = new GlobalConfig.Builder()
 .outputDir(filePath)//生成的输出路径
 .author("lizi")//生成的作者名字
 //.enableSwagger() //开启swagger,需要添加swagger依赖并配置
 .dateType(DateType.TIME_PACK)//时间策略
 .commentDate("yyyy年MM月dd日")//格式化时间格式
 .disableOpenDir()//禁止打开输出目录,默认false
 .fileOverride()//覆盖生成文件
 .build();

 /**
 * 包配置
 */
 PackageConfig packages = new PackageConfig.Builder()
 .entity("pojo")//实体类包名
 .parent("com.xja.application")//父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
 .controller("web")//控制层包名
 .mapper("mapper")//mapper层包名
 .xml("mapper.xml")//数据访问层xml包名
 .service("service")//service层包名
 .serviceImpl("service.impl")//service实现类包名
 //.other("output")//输出自定义文件时的包名
 .pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + "/src/main/resources/mapper")) //路径配置信息,就是配置各个文件模板的路径信息,这里以mapper.xml为例
 .build();
 /**
 * 模板配置
 */

 // 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
 // String templatePath = "/templates/mapper.xml.vm";



 TemplateConfig template = new TemplateConfig.Builder()
// .disable()//禁用所有模板
 //.disable(TemplateType.ENTITY)禁用指定模板
// .service(filePath + "/service.java")//service模板路径
// .serviceImpl(filePath + "/service/impl/serviceImpl.java")//实现类模板路径
// .mapper(filePath + "/mapper.java")//mapper模板路径
// .mapperXml("/templates/mapper.xml")//xml文件模板路路径
// .controller(filePath + "/controller")//controller层模板路径
 .build();

 /**
 * 注入配置,自定义配置一个Map对象
 */
// Map<String,Object> map = new HashMap<>();
// map.put("name","young");
// map.put("age","22");
// map.put("sex","男");
// map.put("description","深情不及黎治跃");
//
// InjectionConfig injectionConfig = new InjectionConfig.Builder()
// .customMap(map)
// .build();


 /**
 * 策略配置开始
 */
 StrategyConfig strategyConfig = new StrategyConfig.Builder()
 .enableCapitalMode()//开启全局大写命名
 //.likeTable()模糊表匹配
 .addInclude(getTables(s))//添加表匹配,指定要生成的数据表名,不写默认选定数据库所有表
 .addTablePrefix("tb_", "sys_","bus_","rel_","dic_") //设置忽略表前缀
 //.disableSqlFilter()禁用sql过滤:默认(不使用该方法)true
 //.enableSchema()启用schema:默认false

 .entityBuilder() //实体策略配置
 //.disableSerialVersionUID()禁用生成SerialVersionUID:默认true
 .enableChainModel()//开启链式模型
 .enableLombok()//开启lombok
 .enableRemoveIsPrefix()//开启 Boolean 类型字段移除 is 前缀
 .enableTableFieldAnnotation()//开启生成实体时生成字段注解
 //.addTableFills()添加表字段填充
 .naming(NamingStrategy.underline_to_camel)//数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
 .columnNaming(NamingStrategy.underline_to_camel)//表字段映射实体属性命名规则:默认null,不指定按照naming执行
 .idType(IdType.AUTO)//添加全局主键类型
 .formatFileName("%s")//格式化实体名称,%s取消首字母I
 .build()

 .mapperBuilder()//mapper文件策略
 .enableMapperAnnotation()//开启mapper注解
 .enableBaseResultMap()//启用xml文件中的BaseResultMap 生成
 .enableBaseColumnList()//启用xml文件中的BaseColumnList
 //.cache(缓存类.class)设置缓存实现类
 .formatMapperFileName("%sMapper")//格式化Dao类名称
 .formatXmlFileName("%sMapper")//格式化xml文件名称
 .build()

 .serviceBuilder()//service文件策略
 .formatServiceFileName("%sService")//格式化 service 接口文件名称
 .formatServiceImplFileName("%sServiceImpl")//格式化 service 接口文件名称
 .build()

 .controllerBuilder()//控制层策略
 //.enableHyphenStyle()开启驼峰转连字符,默认:false
 .enableRestStyle()//开启生成`@RestController`
 .formatFileName("%sController")//格式化文件名称
 .build();
 /*至此,策略配置才算基本完成!*/

 /**
 * 将所有配置项整合到AutoGenerator中进行执行
 */


 generator.global(global)
 .template(template)
// .injection(injectionConfig)
 .packageInfo(packages)
 .strategy(strategyConfig)
 .execute();
 }

 // 处理 all 情况
 protected static List<String> getTables(String tables) {
 return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
 }
}

(4)在SaleController接待层中编写展示数据的代码(分页插件以及条件查询)

plain
package com.xja.application.web;

import com.xja.application.service.SaleService;
import com.xja.application.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * `@author` lizi
 * `@since` 2025年09月13日
 */
`@RestController`
`@RequestMapping`("/sale")
public class SaleController {
 `@Autowired`
 private SaleService saleService;

 `@GetMapping`("getSaleList")//查询展示数据(分页条件查询)
 public R getSaleList(
 `@RequestParam`(value = "pageNum",defaultValue = "1",required = false) int pageNum,
 `@RequestParam`(value = "pageSize",defaultValue = "5",required = false) int pageSize,
 `@RequestParam`(value = "saleType",defaultValue = "",required = false) String saleType,
 `@RequestParam`(value = "saleOrderCustom",defaultValue = "",required = false) String saleOrderCustom
 ) {
 return saleService.getSaleList(pageNum,pageSize,saleType,saleOrderCustom);
 }

 `@GetMapping`("/exportExcel")//导出数据
 public R exportExcel(`@RequestParam`(value = "pageNum",defaultValue = "1",required = false) int pageNum,
 `@RequestParam`(value = "pageSize",defaultValue = "5",required = false) int pageSize,
 `@RequestParam`(value = "saleType",defaultValue = "",required = false) String saleType,
 `@RequestParam`(value = "saleOrderCustom",defaultValue = "",required = false) String saleOrderCustom
 ) {
 return saleService.exportExcel(pageNum,pageSize,saleType,saleOrderCustom);
 }
}

(5)对应的控制层接口代码以及实习类

接口:

plain
package com.xja.application.service;

import com.xja.application.pojo.Sale;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xja.application.utils.R;

/**
 * <p>
 * 服务类
 * </p>
 *
 * `@author` lizi
 * `@since` 2025年09月13日
 */
public interface SaleService extends IService<Sale> {

 R getSaleList(int pageNum, int pageSize, String saleType, String saleOrderCustom);

 R exportExcel(int pageNum, int pageSize, String saleType, String saleOrderCustom);
}
实现类:
plain
package com.xja.application.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xja.application.pojo.Sale;
import com.xja.application.mapper.SaleMapper;
import com.xja.application.service.SaleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xja.application.utils.R;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * `@author` lizi
 * `@since` 2025年09月13日
 */
`@Service`
public class SaleServiceImpl extends ServiceImpl<SaleMapper, Sale> implements SaleService {
 `@Autowired`
 private SaleMapper saleMapper;

 `@Override`
 public R getSaleList(int pageNum, int pageSize, String saleType, String saleOrderCustom) {
 PageHelper.startPage(pageNum,pageSize);
 LambdaQueryWrapper<Sale> queryWrapper = new LambdaQueryWrapper();
 if (StringUtils.isNotEmpty(saleType)){
 queryWrapper.eq(Sale::getSaleType,saleType);
 }
 if (StringUtils.isNotEmpty(saleOrderCustom)){
 queryWrapper.like(Sale::getSaleOrderCustom,saleOrderCustom);
 }
 List<Sale> sales = saleMapper.selectList(queryWrapper);
 return R.Success("获取Sale返回成功",new PageInfo(sales));
 }

 `@Override`
 public R exportExcel(int pageNum, int pageSize, String saleType, String saleOrderCustom) {
 PageHelper.startPage(pageNum,pageSize);
 LambdaQueryWrapper<Sale> queryWrapper = new LambdaQueryWrapper();
 if (StringUtils.isNotEmpty(saleType)){
 queryWrapper.eq(Sale::getSaleType,saleType);
 }
 if (StringUtils.isNotEmpty(saleOrderCustom)){
 queryWrapper.like(Sale::getSaleOrderCustom,saleOrderCustom);
 }
 List<Sale> sales = saleMapper.selectList(queryWrapper);
 Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("销售报表", "第一项"), Sale.class, sales);
 FileOutputStream fileOutputStream = null;
 try {
 fileOutputStream = new FileOutputStream(new File("D:/1-java/120/销售报表.xlsx"));
 workbook.write(fileOutputStream);
 } catch (IOException e) {
 throw new RuntimeException(e);
 }finally {
 try {
 fileOutputStream.close();
 } catch (IOException e) {
 throw new RuntimeException(e);
 }
 }
 return R.Success("导出成功");
 }
}

(6)编写前端展示页面(在前端vue项目下创建一个为poi的文件夹,当前文件夹下创建一个名为Excel.vue的展示页面)

(7)编写Excel.vue中代码(代码中已经包含导出)

plain
<script setup>
import {reactive} from "vue";
import http from "@/utils/http";
import {ElMessage} from "element-plus";

const data = reactive({
 list:[],
 //分页的相关参数
 total:0,
 pageNum:1,
 pageSize:5,
 saleType:'', //订单类型
 saleOrderCustom:'' //下单客户
})

//获取后端数据用于展示
const getSaleList = () => {
 http.get('/sale/getSaleList',{
 params:{
 pageNum:data.pageNum,
 pageSize:data.pageSize,
 saleType:data.saleType,
 saleOrderCustom:data.saleOrderCustom,
 }
 }).then(res => {
 data.list = res.data.list
 data.total = res.data.total
 data.pageNum = res.data.pageNum
 data.pageSize = res.data.pageSize
 })
}
getSaleList()

//分页的2个方法
const handleSizeChange = (val) => {
 data.pageSize = val
 getSaleList()
}
const handleCurrentChange = (val) => {
 data.pageNum = val
 getSaleList()
}

//导出数据
const exportExcel = () => {
 http.get('/sale/exportExcel',{
 params:{
 pageNum:data.pageNum,
 pageSize:data.pageSize,
 saleType:data.saleType,
 saleOrderCustom:data.saleOrderCustom,
 }
 }).then(res => {
 if(res.code === 100200){//成功
 ElMessage({
 message: res.data,
 type: 'success',
 })
 }else {
 ElMessage({
 message: res.msg,
 type: 'success',
 })
 }
 })
}
</script>

<template>

 <el-button type="danger" `@click`="exportExcel">导出数据</el-button>
 <br><br>
 <el-form :inline="true" :model="formInline" class="demo-form-inline">
 <el-form-item label="订单类型" style="width: 300px;">
 <el-select
 v-model="data.saleType"
 placeholder="请选择您想要查看的类型"
 clearable
 >
 <el-option label="暂时不选" value="" />
 <el-option label="普通售卖" value="0" />
 <el-option label="工程单" value="1" />
 </el-select>
 </el-form-item>
 <el-form-item label="下单客户">
 <el-input v-model="data.saleOrderCustom" placeholder="模糊查询" clearable />
 </el-form-item>
 <el-form-item>
 <el-button type="primary" `@click`="getSaleList">查询</el-button>
 </el-form-item>
 </el-form>
 <el-table :data="data.list" border style="width: 100%" >
 <el-table-column label="序号" type="index" width="70" align="center" />
 <el-table-column prop="saleType" label="订单类型" width="120" align="center" >
 <template #default="scope">
 <span v-if="scope.row.saleType == 0">普通售卖</span>
 <span v-if="scope.row.saleType == 1" style="color:red;">工程单</span>
 <span></span>
 </template>
 </el-table-column>
 <el-table-column prop="saleInfo" label="售卖信息" width="280" align="center" />
 <el-table-column prop="saleAmount" label="总金额" width="120" align="center" />
 <el-table-column prop="saleReceiveAmount" label="结款金额" width="120" align="center" />
 <el-table-column prop="saleState" label="结款状态" width="120" align="center" >
 <template #default="scope">
 <span v-if="scope.row.saleState == 0">未结清</span>
 <span v-if="scope.row.saleState == 1">已结清</span>
 </template>
 </el-table-column>
 <el-table-column prop="saleOrderCustom" label="下单客户" width="120" align="center" />
 <el-table-column prop="saleOrderCustomPhone" label="客户短话" width="120" align="center" />
 <el-table-column prop="saleAddress" label="安装地址" width="180" align="center" />
 <el-table-column prop="saleOrderInstallState" label="是否安装" width="120" align="center" >
 <template #default="scope">
 <span v-if="scope.row.saleOrderInstallState == 0">未安装</span>
 <span v-if="scope.row.saleOrderInstallState == 1">已安装</span>
 </template>
 </el-table-column>
 <el-table-column prop="saleDate" label="售卖时间" width="180" align="center" />

 <el-table-column label="操作" fixed="right" width="120" align="center">
 <template #default="scope">
 <el-popconfirm `@confirm`="handleDelete(scope.row.id)" title="你确定删除?">
 <template #reference>
 <el-button size="small" type="danger" >删除</el-button>
 </template>
 </el-popconfirm>
 </template>
 </el-table-column>
 </el-table>
 <br>
 <el-pagination
 v-model:current-page="data.pageNum"
 v-model:page-size="data.pageSize"
 :page-sizes="[5, 10, 15, 20]"
 background="true"
 layout="total, sizes, prev, pager, next, jumper"
 :total="data.total"
 `@size`-change="handleSizeChange"
 `@current`-change="handleCurrentChange"
 />
</template>

<style scoped>

</style>

导入

(1)在导出数据的代码下方加入导入数据按钮

(2)当点击导入按钮时或出现弹窗(加入弹窗代码)

plain
<!--导入文件--->
<el-dialog
 v-model="data.dialogVisible"
 title="导入文件"
 width="30%"
 :before-close="handleClose"
>
 <el-upload
 ref="uploadRef"
 v-model:file-list="data.fileList"
 class="upload-demo"
 :action="http.defaults.baseURL+'sale/importExcel'"
 :on-preview="handlePreviewSingleFile"
 :on-remove="handleRemoveSingleFile"
 :limit="1"
 :before-upload="beforeUploadSingleFile"
 :on-success="successSingleFile"
 :on-exceed="handleExceedSingleFile"
 >
 <template #trigger>
 <el-button type="primary">上传文件</el-button>
 </template>
 <br>
 <template #tip>
 <div class="el-upload__tip" style="color: red">
 上传Excel类型,且不超过600MB
 </div>
 </template>
 </el-upload>
</el-dialog>

(3)在data下方创建两个参数分别是

plain
dialogVisible:false, //控制导入文件弹窗
fileList:[],//储存文件

(4)声明方法

plain
const importExcel = () => {
 data.dialogVisible = true;
}

//成功上传文件到FastDfs并且返回路径之后执行的方法
const successSingleFile = (response, uploadFile, uploadFiles) => {
 if(response.code === 100200){//成功
 ElMessage({
 message: response.msg,
 type: 'success',
 })
 }else {
 ElMessage({
 message: response.msg,
 type: 'success',
 })
 }
 data.dialogVisible = false;
 data.fileList = [];
 getSaleList();
}

(5)编写后端SaleController控制层代码

plain
`@PostMapping`("importExcel")//Excel数据导入数据库
public R importExcel(`@RequestBody` MultipartFile file) {
 return saleService.importExcel(file);
}

对应的接口以及接口实现类

实现类

plain
`@Override`
public R importExcel(MultipartFile file) {
 //判断是否为空
 if (file.isEmpty()){
 return R.Failed("文件内容为空");
 }
 //判断格式是否错误
 String xls="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
 String xlsx="application/vnd.ms-excel";
 if (!xls.equals(file.getContentType())&&!xlsx.equals(file.getContentType())){
 return R.Failed("上传文件格式错误");
 }
 //设置导入对象
 ImportParams importParams = new ImportParams();
 //读取第几个sheet
 importParams.setStartSheetIndex(0);
 //每次读取几个sheet
 importParams.setSheetNum(1);
 //标题占几行
 importParams.setTitleRows(1);
 //头部占几行
 importParams.setHeadRows(1);
 //生成导入execl对象
 try {
 List<Sale> salelist = ExcelImportUtil.importExcel(file.getInputStream(), Sale.class, importParams);
 salelist.forEach(sale -> {
 saleMapper.insert(sale);
 });
 return R.Success("导入成功");
 } catch (Exception e) {
 e.printStackTrace();
 return R.Success("导入失败");
 }
}

从数据库导出word文档

(1)编写其那段vue代码,在Excel.vue中编写代码

(2)在删除代码上方添加一个打印的按钮,并且添加点击事件将id传到后端

(3)点击事件代码

plain
//打印合同
const printWord = (id) => {
 http({
 method: 'get',
 url: 'sale/printWord/' + id,
 responseType: "blob", //定义为blob
 }).then(res => {
 let blob = new Blob([res])
 let downloadElement = document.createElement('a')
 let href = window.URL.createObjectURL(blob) // 创建下载的链接
 downloadElement.href = href
 downloadElement.download = '合同.docx' // 下载后文件名
 document.body.appendChild(downloadElement)
 downloadElement.click() // 点击下载
 document.body.removeChild(downloadElement) // 下载完成移除元素
 window.URL.revokeObjectURL(href) // 释放掉blob对象
 })
}

(4)编写后端SaleController中控制层代码

plain
`@GetMapping`("printWord/{id}")//将数据库导出成word文档
public void printWord(`@PathVariable`("id") Integer id,HttpServletResponse response) {
 saleService.printWord(id,response);
}

对应的接口

接口对应的实现类

plain
`@Override`
public void printWord(Integer id, HttpServletResponse response) {
 try {
 //获取模板文档
 File rootFile =new File(ResourceUtils.getURL("classpath:").getPath());
 File templateFile= new File(rootFile,"word.docx");
 //查出数据
 LambdaQueryWrapper<Sale> wrapper = new LambdaQueryWrapper<>();
 wrapper.eq(Sale::getId,id);
 Map<String, Object> map = this.getMap(wrapper);
 //映射为模板
 XWPFDocument word = WordExportUtil.exportWord07(templateFile.getPath(),map);
 String filename = "万代兴门业销售合同.docx";
 //导出
 response.setHeader("content-disposition","attachment;filename="+new String(filename.getBytes(),"ISO8859-1"));
 response.setContentType("application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet");
 word.write(response.getOutputStream());
 //释放
 word.close();
 }catch (Exception e){
 e.printStackTrace();
 }
}