外观
第一部分:导出
(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();
}
}