1、如何搭建项目,搭建项目的过程
1、新建maven项目
2、在pom.xml中配置相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<mysql.version>8.0.30</mysql.version>
<junit.version>4.12</junit.version>
<swagger.version>3.0.0</swagger.version>
<lombok.version>1.18.24</lombok.version>
<hutool.version>5.8.5</hutool.version>
<druid.version>1.2.11</druid.version>
<jackson.version>2.13.4</jackson.version>
<fastjson2.version>2.0.23</fastjson2.version>
<commonsio.version>2.11.0</commonsio.version>
<aspectj-weaver.version>1.9.7</aspectj-weaver.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<hibernate-validator.version>6.2.3.Final</hibernate-validator.version> <pagehelper.version>5.2.0</pagehelper.version>
</properties>
<dependencies>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!--spring-boot-web相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<!--mybatis-plus-generator需要此依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!--fastjson 工具-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!--aop相关-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj-weaver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--加解密、编码-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commonsio.version}</version>
</dependency>
<!-- <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.3.Final</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!--阿里云短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.2.5</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.20</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!--定时任务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--springboot打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3、编写一个启动类application
4、编写一个配置文件application.yml,指定端口号
后端:编写controller层,service层,mapper层,pojo层(这里就不详细介绍了,之前的发布的spring项目中有详细代码)
1、需要强调的是,在springboot项目中进行分页我们需要单独写一个配置类来进行配置
package cn.jiyun.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.poi.hssf.record.pivottable.PageItemRecord;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MPConfig {
/*@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}*/
//可以用这种简单方式替换上面那种方式
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
2、要想使用redis缓存时,也需要进行配置
package cn.jiyun.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// 设置redis连接
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// 将redisTemplate的序列化方式更改为StringRedisSerializer
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
3、图片上传时的配置
package cn.jiyun.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//文件上传路径
String path = "D:/upload/";
//访问的时候,http://localhost:82/images/16327360-765e-43ac-b008-d036f3caa43a.jpg
registry.addResourceHandler("/images/**").addResourceLocations("file:"+path+"/");
}
}
前端代码:
主页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/vue.js"></script>
<link rel="stylesheet" href="/css/elementUI.css">
<script src="/js/elementUI.js"></script>
<script src="/js/axios.js"></script>
<script src="/js/util.js"></script>
<link rel="stylesheet" href="/css/upload.css">
</head>
<body>
<div id="app">
<!--<el-image style="width:100px; height: 100px" src="http://localhost:82/images/66310e43-c126-420b-87d9-8d18f2eeafde.gif"></el-image>-->
姓名:<el-input v-model="requestParam.name" placeholder="请输入内容" style="width: 200px"></el-input>
日期:<el-date-picker
v-model="requestParam.start"
type="date"
placeholder="开始日期">
</el-date-picker>--
<el-date-picker
v-model="requestParam.end"
type="date"
placeholder="结束日期">
</el-date-picker>
品牌:
<el-select v-model="requestParam.bid" placeholder="请选择">
<el-option
v-for="item in brandList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button type="primary" @click="showAllTea">搜索</el-button>
<el-button type="primary" @click="reset">重置</el-button>
<el-button type="primary" @click="addPage">添加</el-button>
<el-button type="danger" @click="PLDelete">批量删除</el-button>
<!--<el-button type="primary" @click="tongjiLine">折线图</el-button>-->
<el-button type="primary" @click="tongjiLine">柱状图</el-button>
<el-button type="primary" @click="tongjiPie">饼状图</el-button>
<el-button type="primary" @click="exportData">导出</el-button>
<el-button type="primary" @click="importDataPage">导入</el-button>
<el-dialog :title="mode.title" :visible.sync="dialogFormVisible">
<el-form :model="form" >
<el-form-item label="名称" label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off" @blur="nameAjax(form.name)"></el-input>
</el-form-item>
<el-form-item label="价格" label-width="formLabelWidth">
<el-input v-model="form.price" autocomplete="off" id="price" @blur="price(form.price)"></el-input>
</el-form-item>
<el-form-item label="vip价格" label-width="formLabelWidth">
<el-input v-model="form.vprice" autocomplete="off" readonly="true" style="width:300px"></el-input>此内容不可输入
</el-form-item>
<el-form-item label="地址" label-width="formLabelWidth">
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="详情" label-width="formLabelWidth">
<el-input v-model="form.detail" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="日期" label-width="formLabelWidth">
<el-date-picker
v-model="form.time"
type="date"
placeholder="日期">
</el-date-picker>
</el-form-item>
<el-form-item label="状态" label-width="formLabelWidth">
<el-radio-group v-model="form.status">
<el-radio :label="1">在售</el-radio>
<el-radio :label="2">售罄</el-radio>
<el-radio :label="3">待审核</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="品牌" label-width="formLabelWidth">
<el-select v-model="form.bid" placeholder="请选择品牌">
<el-option
v-for="item in brandList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="头像" label-width="formLabelWidth">
<el-upload
class="avatar-uploader"
action="/tea/teaUpload"
:show-file-list="false"
:on-success="handleAvatarSuccess">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button v-if="flag==false" @click="dialogFormVisible = false">取 消</el-button>
<el-button v-if="flag==false" type="primary" @click="addTea">确 定</el-button>
</div>
</el-dialog>
<!--导入-->
<el-dialog title="导入" :visible.sync="dialogExcelVisible">
<el-upload
class="avatar-uploader"
action="/tea/importDataPage"
name="fileName"
:show-file-list="false"
:on-success="handleExcelSuccess">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-dialog>
<el-table
:data="page.records"
stripe
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="id"
label="编号" width="60px">
</el-table-column>
<el-table-column
prop="name"
label="姓名" width="100px">
</el-table-column>
<el-table-column
prop="price"
label="价格">
</el-table-column>
<el-table-column
prop="vprice"
label="vip价格">
</el-table-column>
<el-table-column
prop="time"
label="日期">
<template slot-scope="scope">
{{scope.row.time|format('yyyy-MM-dd')}}
</template>
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
<el-table-column
prop="detail"
label="详情">
</el-table-column>
<el-table-column
prop="status"
label="状态">
<template slot-scope="scope">
{{scope.row.status==1?'在售':scope.row.status==2?'售罄':'待审核'}}
</template>
</el-table-column>
<el-table-column
prop="bname"
label="品牌">
</el-table-column>
<el-table-column
prop="img"
label="头像">
<template slot-scope="scope">
<el-image style="width:100px; height: 100px" :src="scope.row.img">
</el-image>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.current"
:page-sizes="[2, 10, 300, 400]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</body>
<script>
new Vue({
el:"#app",
data:{
imageUrl:"",
flag:false,
requestParam:{},
page:{},
pageParam:{
current:1,
size:3
},
brandList:[],
dialogFormVisible:false,
mode:{
title:"",
url:"",
},
form:{},
plArr:[],
dialogExcelVisible:false,
},
methods:{
handleExcelSuccess(res,file){
this.dialogExcelVisible=false;
this.initData();
},
importDataPage(){
this.dialogExcelVisible=true;
},
exportData(){
location="/tea/exportData";
},
nameAjax(name){
axios.post(`/tea/nameAjax?name=`+name).then(res => {
if (res.data) {
alert("可以")
} else {
alert("bu")
}
})
},
handleAvatarSuccess(res, file) {
debugger;
this.imageUrl = URL.createObjectURL(file.raw);
alert(res)
this.form.img=res;
},
tongjiLine(){
location="tongji_line.html";
},
tongjiPie(){
location="tongji_pie.html";
},
guanbi(){
this.dialogFormVisible=false;
this.showAllTea();
},
handleSelectionChange(val){
this.plArr=[];
for (let i = 0; i < val.length; i++) {
this.plArr.push( val[i].id);
}
},
PLDelete(){
if(this.plArr.length==0){
this.$message.error("至少选中一条");
return;
}
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post(`/tea/teaPLDel?plArr=${this.plArr}`).then(res => {
if (res, data) {
this.$message.success("删除成功");
this.showAllTea();
} else {
this.$message.error("删除失败");
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
handleDelete(id) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post("/tea/teaDel?id=" + id).then(res => {
if (res.data) {
this.$message.success("删除成功");
this.showAllTea();
} else {
this.$message.error("删除失败");
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
handleEdit(val) {
this.mode.title="修改";
this.mode.url="/tea/updateTea";
this.imageUrl=val.img;
this.form=val;
this.dialogFormVisible=true;
},
price(price){
this.form.vprice=(price*0.8).toFixed(2);
},
handleSizeChange(val){
this.pageParam.size=val;
this.showAllTea();
},
handleCurrentChange(val){
this.pageParam.current=val;
this.showAllTea();
},
reset(){
this.requestParam={};
},
addPage(){
this.mode.title="添加";
this.mode.url="/tea/teaAdd";
this.imageUrl="";
this.form={};
this.dialogFormVisible=true;
},
addTea(){
axios.post(this.mode.url,this.form).then(res=>{
if(res.data){
this.dialogFormVisible=false;
this.$message.success(this.mode.title+"成功");
this.showAllTea();
}else{
this.$message.error("操作失败");
}
});
},
showAllTea(){
axios.post(`/tea/teaList?current=${this.pageParam.current}&size=${this.pageParam.size}`,this.requestParam).then(res=>{
this.page=res.data;
});
},
showAllBrand(){
axios.post(`/tea/brandList`).then(res=>{
this.brandList=res.data;
});
}
},
created(){
this.showAllTea();
this.showAllBrand();
},
filters:{
format(value,arg){
function dateFormat(date, format) {
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/);
if (mts && mts.length >= 3) {
date = parseInt(mts[2]);
}
}
date = new Date(date);
if (!date || date.toUTCString() == "Invalid Date") {
return "";
}
var map = {
"M": date.getMonth() + 1, //月份
"d": date.getDate(), //日
"h": date.getHours(), //小时
"m": date.getMinutes(), //分
"s": date.getSeconds(), //秒
"q": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
format = format.replace(/([yMdhmsqS])+/g, function (all, t) {
var v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length);
}
return all;
});
return format;
}
return dateFormat(value,arg);
}
},
})
</script>
</html>
饼状图页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/css/elementUI.css">
<script src="/js/vue.js"></script>
<script src="/js/elementUI.js"></script>
<script src="/js/axios.js"></script>
<script src="/js/echarts.js"></script>
</head>
<body>
<div id="app">
<div id="chart" style="height:600px;width:60%;float: left"></div>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {},
methods: {
initData() {
var myChart = echarts.init(document.getElementById('chart'));
axios.get(`/tea/tongjiPie`).then(res => {
var option = {
title: {
text: '部门人数占比',
subtext: '',
x: 'center'
},
tooltip: {//提示框组件
trigger: 'item',//触发类型,在饼形图中为item
formatter: "{a} <br/>{b} : {c} ({d}%)"//提示内容格式
},
legend: {
orient: 'vertical',
left: 'left',
data: res.data.names
},
series: [
{
name: '部门人数占比',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: res.data.nums,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
myChart.setOption(option);
})
},
},
mounted() {
this.initData();
}
})
</script>
</html>
柱状图和线状图的区别在于前端的一个单词(bar柱状图 line线状图)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/css/elementUI.css">
<script src="/js/vue.js"></script>
<script src="/js/elementUI.js"></script>
<script src="/js/axios.js"></script>
<script src="/js/echarts.js"></script>
</head>
<body>
<div id="app">
<div id="chart" style="height:600px;width:60%;float: left"></div>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {},
methods: {
initData() {
//第一个data是统计的名称eg宿舍号
//第二个data是统计的数量eg:num
let myChart = echarts.init(document.getElementById('chart'));
axios.get(`/tea/tongjiLine`).then(res => {
let option = {
title: {
text: '部门人数'
},
tooltip: {},
legend: {
data: ['部门人数']
},
xAxis: {
data: res.data.names
},
yAxis: {
type: 'value'
},
series: [{
name: '部门人数',
type: 'bar',
data: res.data.nums
}]
};
myChart.setOption(option);
})
},
},
mounted() {
this.initData();
}
})
</script>
</html>
后端导出:
其中包括导入导出,在之前的博客中没讲解到导入和导出,在这里介绍一下
导出代码:
@RequestMapping("exportData")
public void exportData(HttpServletResponse response) throws Exception{
// 准备数据
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<TeaVo> list=teaService.exportData();
if(list.size()>0 && list!=null){
// 准备表头信息
String[] title={"姓名","价格","vip价格","日期","地址","详情","状态","品牌","头像"};
// 创建xssworkbook
XSSFWorkbook workbook = new XSSFWorkbook();
// 得到sheet对象
XSSFSheet sheet = workbook.createSheet();
// 得到行对象
XSSFRow cells = sheet.createRow(0);
// 将标题写入excel中
for (int i = 0; i < title.length; i++) {
cells.createCell(i).setCellValue(title[i]);
}
// 循环要导出的数据
for (int i = 0; i < list.size(); i++) {
// 得到每条数据的对象
TeaVo vo = list.get(i);
// 创建存放数据的表格
XSSFRow row = sheet.createRow(i + 1);
// 将数据存放在excel表格中
row.createCell(0).setCellValue(vo.getName());
row.createCell(1).setCellValue(vo.getPrice());
row.createCell(2).setCellValue(vo.getVprice());
row.createCell(3).setCellValue(sdf.format(vo.getTime()));
row.createCell(4).setCellValue(vo.getAddress());
row.createCell(5).setCellValue(vo.getDetail());
row.createCell(6).setCellValue(vo.getStatus()==1?"在售":vo.getStatus()==2?"售罄":"待审核");
row.createCell(7).setCellValue(vo.getBname());
row.createCell(8).setCellValue(vo.getImg());
}
// 7. 将Workbook写入文件
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("茶叶信息.xlsx", "UTF-8"));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "application/octet-stream");
workbook.write(response.getOutputStream());
}
}
后端导入代码:
@RequestMapping("importDataPage")
public void importDataPage(MultipartFile fileName) throws Exception{
// riqi
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 创建工作簿对象并读取文件
XSSFWorkbook workbook = new XSSFWorkbook(fileName.getInputStream());
// 得到sheet对象
XSSFSheet sheet = workbook.getSheetAt(0);
// 获取有数据的行数有多少行
int number = sheet.getPhysicalNumberOfRows();
// 遍历每一行数据
for (int i = 1; i < number; i++) {
// 得到每一行的对象
XSSFRow row = sheet.getRow(i);
// 得到姓名
String name = row.getCell(0).getStringCellValue();
Double price = row.getCell(1).getNumericCellValue();
Double vprice = row.getCell(2).getNumericCellValue();
Date time = sdf.parse(row.getCell(3).getStringCellValue()) ;
String address = row.getCell(4).getStringCellValue();
String detail = row.getCell(5).getStringCellValue();
Integer status = row.getCell(6).getStringCellValue().equals("在售")?1:row.getCell(5).getStringCellValue().equals("售罄")?2:3;
String bname = row.getCell(7).getStringCellValue();
String img = row.getCell(8).getStringCellValue();
LambdaQueryWrapper<Brand> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Brand::getName,bname);
Brand brand = brandMapper.selectOne(wrapper);
Integer bid=null;
if(brand==null){
Brand brand1 = new Brand();
brand1.setName(bname);
brandMapper.insert(brand1);
bid=brand1.getId();
}else{
bid=brand.getId();
}
Tea tea = new Tea(name,price,vprice,time,address,detail,status,bid,1,img);
// 执行添加方法
teaService.teaAdd(tea);
}
}
后端饼状图:
public Map tongjiPie() {
HashMap<Object, Object> map = new HashMap<>();
List<String> names = new ArrayList<>();
List<Map> list=teaMapper.tongjiLine();
for (Map map1 : list) {
names.add(map1.get("name").toString());
}
map.put("names",names);
map.put("nums",list);
return map;
}
后端线状图:
public Map tongjiLine() {
HashMap<Object, Object> map = new HashMap<>();
List<String> names = new ArrayList<>();
List<Integer> nums = new ArrayList<>();
List<Map> list=teaMapper.tongjiLine();
for (Map map1 : list) {
names.add(map1.get("name").toString());
nums.add(Integer.parseInt(map1.get("value").toString()));
}
map.put("names",names);
map.put("nums",nums);
return map;
}