使用SpringBoot开发(完整项目)

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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘猫_A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值