• Day01-Java-报表以及表格


    Java报表以及表格

    在这里插入图片描述

    在学习Java报表展示以及图形化输出的技术的时候,在学习之前,我们一定要明白为什么要学习一门新的技术???

    【答案】:
    项目中需要,这门新的技术对我们目前的项目有这是执行的帮助,比如说可以帮助提高项目的执行效率或者是帮助解决项目中的某个实际的需求。
    不然我们学习一门新的技术就是在白白的浪费我们的声明,所以,我们如果没有搞清楚为什么学习一门新的技术之前,我们所有的努力都是在欺骗自己。


    最近,由于出差外地忙着做项目,所以没有更新博客,最近也是因为项目中有一个新的需求需要使用到Java的报表技术,所以一这篇博客为引子,希望可以给我带来一些帮助,也同样希望可以帮助到其他的兄弟姐妹。


    前言

    那么废话不多说,我们直接开始整一个项目来初始一下

    项目环境

    1. Spring Boot 2.7.3
    2. MyBatis-plus
    3. MySQL 8.0.28
    4. 开发工具 Spring Suit4
    5. POI excel导出技术

    一、数据库准备

    DROP TABLE IF EXISTS `tb_dept`;
    CREATE TABLE `tb_dept` (
      `id` bigint(20) DEFAULT NULL COMMENT '部门编号',
      `dept_name` varchar(100) DEFAULT NULL COMMENT '部门编号'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_dept
    -- ----------------------------
    INSERT INTO `tb_dept` VALUES ('5', '资产管理部');
    INSERT INTO `tb_dept` VALUES ('6', '质量监察部');
    INSERT INTO `tb_dept` VALUES ('7', '营销部');
    INSERT INTO `tb_dept` VALUES ('1', '销售部');
    INSERT INTO `tb_dept` VALUES ('2', '人事部');
    INSERT INTO `tb_dept` VALUES ('3', '财务部');
    INSERT INTO `tb_dept` VALUES ('4', '技术部');
    
    -- ----------------------------
    -- Table structure for tb_province
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_province`;
    CREATE TABLE `tb_province` (
      `id` bigint(50) NOT NULL,
      `name` varchar(100) DEFAULT NULL COMMENT '省份或直辖市或特别行政区名称',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_province
    -- ----------------------------
    INSERT INTO `tb_province` VALUES ('1', '北京市');
    INSERT INTO `tb_province` VALUES ('2', '天津市');
    INSERT INTO `tb_province` VALUES ('3', '上海市');
    INSERT INTO `tb_province` VALUES ('4', '重庆市');
    INSERT INTO `tb_province` VALUES ('5', '河北省');
    INSERT INTO `tb_province` VALUES ('6', '山西省');
    INSERT INTO `tb_province` VALUES ('7', '辽宁省');
    INSERT INTO `tb_province` VALUES ('8', '吉林省');
    INSERT INTO `tb_province` VALUES ('9', '黑龙江省');
    INSERT INTO `tb_province` VALUES ('10', '江苏省');
    INSERT INTO `tb_province` VALUES ('11', '浙江省');
    INSERT INTO `tb_province` VALUES ('12', '安徽省');
    INSERT INTO `tb_province` VALUES ('13', '福建省');
    INSERT INTO `tb_province` VALUES ('14', '江西省');
    INSERT INTO `tb_province` VALUES ('15', '山东省');
    INSERT INTO `tb_province` VALUES ('16', '河南省');
    INSERT INTO `tb_province` VALUES ('17', '湖北省');
    INSERT INTO `tb_province` VALUES ('18', '湖南省');
    INSERT INTO `tb_province` VALUES ('19', '广东省');
    INSERT INTO `tb_province` VALUES ('20', '海南省');
    INSERT INTO `tb_province` VALUES ('21', '四川省');
    INSERT INTO `tb_province` VALUES ('22', '贵州省');
    INSERT INTO `tb_province` VALUES ('23', '云南省');
    INSERT INTO `tb_province` VALUES ('24', '陕西省');
    INSERT INTO `tb_province` VALUES ('25', '甘肃省');
    INSERT INTO `tb_province` VALUES ('26', '青海省');
    INSERT INTO `tb_province` VALUES ('27', '台湾省');
    INSERT INTO `tb_province` VALUES ('28', '内蒙古自治区');
    INSERT INTO `tb_province` VALUES ('29', '广西壮族自治区');
    INSERT INTO `tb_province` VALUES ('30', '西藏自治区');
    INSERT INTO `tb_province` VALUES ('31', '宁夏回族自治区');
    INSERT INTO `tb_province` VALUES ('32', '新疆维吾尔自治区');
    INSERT INTO `tb_province` VALUES ('33', '香港特别行政区');
    INSERT INTO `tb_province` VALUES ('34', '澳门特别行政区');
    
    -- ----------------------------
    -- Table structure for tb_resource
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_resource`;
    CREATE TABLE `tb_resource` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) DEFAULT NULL,
      `price` double(10,1) DEFAULT NULL,
      `user_id` bigint(20) DEFAULT NULL,
      `need_return` tinyint(1) DEFAULT NULL COMMENT '是否需要归还',
      `photo` varchar(200) DEFAULT NULL COMMENT '照片',
      PRIMARY KEY (`id`),
      KEY `fk_user_id` (`user_id`),
      CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `tb_user` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_resource
    -- ----------------------------
    INSERT INTO `tb_resource` VALUES ('1', '记录本', '2.0', '3', '0', '\\resource_photos\\3\\1.jpg');
    INSERT INTO `tb_resource` VALUES ('2', '笔记本电脑', '7000.0', '3', '1', '\\resource_photos\\3\\2.jpg');
    INSERT INTO `tb_resource` VALUES ('3', '办公桌', '1000.0', '3', '1', '\\resource_photos\\3\\3.jpg');
    INSERT INTO `tb_resource` VALUES ('4', '订书机', '50.0', '4', '1', '\\resource_photos\\4\\1.jpg');
    INSERT INTO `tb_resource` VALUES ('5', '双面胶带', '5.0', '4', '0', '\\resource_photos\\4\\2.jpg');
    INSERT INTO `tb_resource` VALUES ('6', '资料文件夹', '10.0', '4', '0', '\\resource_photos\\4\\3.jpg');
    INSERT INTO `tb_resource` VALUES ('7', '打印机', '1200.0', '4', '1', '\\resource_photos\\4\\4.jpg');
    
    -- ----------------------------
    -- Table structure for tb_user
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_user`;
    CREATE TABLE `tb_user` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
      `user_name` varchar(100) DEFAULT NULL COMMENT '姓名',
      `phone` varchar(15) DEFAULT NULL COMMENT '手机号',
      `province` varchar(50) DEFAULT NULL COMMENT '省份',
      `city` varchar(50) DEFAULT NULL COMMENT '城市',
      `salary` int(10) DEFAULT NULL,
      `hire_date` datetime DEFAULT NULL COMMENT '入职日期',
      `dept_id` bigint(20) DEFAULT NULL COMMENT '部门编号',
      `birthday` datetime DEFAULT NULL COMMENT '出生日期',
      `photo` varchar(200) DEFAULT NULL COMMENT '照片路径',
      `address` varchar(300) DEFAULT NULL COMMENT '现在住址',
      PRIMARY KEY (`id`),
      KEY `fk_dept` (`dept_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_user
    -- ----------------------------
    INSERT INTO `tb_user` VALUES ('1', '大一', '13800000001', '北京市', '北京市', '11000', '2001-01-01 21:18:29', '1', '1981-03-02 00:00:00', '\\static\\user_photos\\1.jpg', '北京市西城区宣武大街1号院');
    INSERT INTO `tb_user` VALUES ('2', '不二', '13800000002', '河北省', '石家庄市', '12000', '2002-01-02 21:18:29', '2', '1982-03-02 00:00:00', '\\static\\user_photos\\2.jpg', '北京市西城区宣武大街2号院');
    INSERT INTO `tb_user` VALUES ('3', '张三', '13800000003', '河北省', '石家庄市', '13000', '2003-03-03 21:18:29', '3', '1983-03-02 00:00:00', '\\static\\user_photos\\3.jpg', '北京市西城区宣武大街3号院');
    INSERT INTO `tb_user` VALUES ('4', '李四', '13800000004', '河北省', '石家庄市', '14000', '2004-02-04 21:18:29', '4', '1984-03-02 00:00:00', '\\static\\user_photos\\4.jpg', '北京市西城区宣武大街4号院');
    INSERT INTO `tb_user` VALUES ('5', '王五', '13800000005', '河北省', '唐山市', '15000', '2005-03-05 21:18:29', '5', '1985-03-02 00:00:00', '\\static\\user_photos\\5.jpg', '北京市西城区宣武大街5号院');
    INSERT INTO `tb_user` VALUES ('6', '赵六', '13800000006', '河北省', '承德市省', '16000', '2006-04-06 21:18:29', '6', '1986-03-02 00:00:00', '\\static\\user_photos\\6.jpg', '北京市西城区宣武大街6号院');
    INSERT INTO `tb_user` VALUES ('7', '沈七', '13800000007', '河北省', '秦皇岛市', '17000', '2007-06-07 21:18:29', '7', '1987-03-02 00:00:00', '\\static\\user_photos\\7.jpg', '北京市西城区宣武大街7号院');
    INSERT INTO `tb_user` VALUES ('8', '酒八', '13800000008', '河北省', '秦皇岛市', '18000', '2008-07-08 21:18:29', '6', '1988-03-02 00:00:00', '\\static\\user_photos\\8.jpg', '北京市西城区宣武大街8号院');
    INSERT INTO `tb_user` VALUES ('9', '第九', '13800000009', '山东省', '德州市', '19000', '2009-03-09 21:18:29', '1', '1989-03-02 00:00:00', '\\static\\user_photos\\9.jpg', '北京市西城区宣武大街9号院');
    INSERT INTO `tb_user` VALUES ('10', '石十', '13800000010', '山东省', '青岛市', '20000', '2010-07-10 21:18:29', '4', '1990-03-02 00:00:00', '\\static\\user_photos\\10.jpg', '北京市西城区宣武大街10号院');
    INSERT INTO `tb_user` VALUES ('11', '肖十一', '13800000011', '山东省', '青岛市', '21000', '2011-12-11 21:18:29', '4', '1991-03-02 00:00:00', '\\static\\user_photos\\11.jpg', '北京市西城区宣武大街11号院');
    INSERT INTO `tb_user` VALUES ('12', '星十二', '13800000012', '山东省', '青岛市', '22000', '2012-05-12 21:18:29', '4', '1992-03-02 00:00:00', '\\static\\user_photos\\12.jpg', '北京市西城区宣武大街12号院');
    INSERT INTO `tb_user` VALUES ('13', '钗十三', '13800000013', '山东省', '济南市', '23000', '2013-06-13 21:18:29', '3', '1993-03-02 00:00:00', '\\static\\user_photos\\13.jpg', '北京市西城区宣武大街13号院');
    INSERT INTO `tb_user` VALUES ('14', '贾十四', '13800000014', '山东省', '威海市', '24000', '2014-06-14 21:18:29', '2', '1994-03-02 00:00:00', '\\static\\user_photos\\14.jpg', '北京市西城区宣武大街14号院');
    INSERT INTO `tb_user` VALUES ('15', '甄世武', '13800000015', '山东省', '济南市', '25000', '2015-06-15 21:18:29', '4', '1995-03-02 00:00:00', '\\static\\user_photos\\15.jpg', '北京市西城区宣武大街15号院');
    
    
    -- ----------------------------
    -- Table structure for tb_month
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_month`;
    CREATE TABLE `tb_month` (
      `name` varchar(2) DEFAULT NULL COMMENT '月份'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_month
    -- ----------------------------
    INSERT INTO `tb_month` VALUES ('01');
    INSERT INTO `tb_month` VALUES ('02');
    INSERT INTO `tb_month` VALUES ('03');
    INSERT INTO `tb_month` VALUES ('04');
    INSERT INTO `tb_month` VALUES ('05');
    INSERT INTO `tb_month` VALUES ('06');
    INSERT INTO `tb_month` VALUES ('07');
    INSERT INTO `tb_month` VALUES ('08');
    INSERT INTO `tb_month` VALUES ('09');
    INSERT INTO `tb_month` VALUES ('10');
    INSERT INTO `tb_month` VALUES ('11');
    INSERT INTO `tb_month` VALUES ('12');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155

    二、项目搭建

    1. 新建controller、mapper、pojo、service、util

    1. 安装Lombok插件

    由于使用的Spring Suit4插件来完成项目的开发工作,在使用Lombok工具的时候会出现Lombok不起作用的情况,所以,这里安装一个Lombok的插件。方便开发,提高开发效率。

    在Spring Suit4或者Eclispe中点击Help-> Install New SoftWare
    然后点击Add 添加一个Lombok的插件,地址输入https://projectlombok.org/p2

    或者不想使用Lombok工具的也可以写getter和setter

    2. 项目初始化

    链接:https://pan.baidu.com/s/1KdZMc-4LbS1w7RUIngLiKw
    提取码:0phg
    这里我是使用的黑马程序员所提供的一个Vue的前端框架

    项目的结构如下图所示:
    在这里插入图片描述
    再部署完成项目后,我们进行访问localhost:8080/list.html,出现下图所示的页面表示我们的项目初始化已经完成。
    在这里插入图片描述

    3. 项目代码分析

    首先我们先看登陆的首页,黑马这个页面的list.html采用的是Vue前端框架内所编写,如果有小伙伴不懂Vue的相关知识,可以去网上搜索,也可以查看我之前所写的Vue的博客借鉴。

    3.1 Create钩子函数初始化页面数据

    在这里插入图片描述
    如果学过Vue的小伙伴知道Vue的生命周期,当调用Create钩子函数后,也就表示Vue的实力已经被创建,此时会有一个判断,判断是否有el,这里可以将el想象成是多条的数据。
    那么此时我们调用了findPage()方法,去获取el

    3.2 调用接口,获取数据

    调用findPage()函数,获取el
    在这里插入图片描述
    调用接口这里使用的是asxios封装的Ajax方法,get(‘url’).then(data){},这里的data就是调用接口返回的数据,将返回的数据放入到事先定义好的userList[]数组中。

    3.3 如何将返回的数据渲染到页面

    这里使用的是Vue的v-for语法,将数组中的数据通过遍历userList数组,将一个一个的记录,渲染到页面上进行显示。
    在这里插入图片描述

    3.4 接下来就是下载的方法

    在这里插入图片描述
    这里面对应了一些js方法,这些方法就是通过Vue的v-on:click=''或者@click=""调用这些方法,我们现在就只需要写这些接口,实现Excel的相关操作就达到了目的。

    那么接下来就展开正式的学习吧

    三、Excel说明

    在企业级的开发中,excel报表是一种最常见的报表需求,Excel报表开发一般分为两种形式:

    1. 为了方便操作,基于Excel的报表批量上传数据,也就是把Excel中的数据导入到系统中。
    2. 通过java代码生成Excel报表,也就是把系统中的数据导出到Excel中,方便阅读。

    3.1 Excel的两种版本

    目前是市面上的Excel分为两种版本,1.Excel2003和Excel2007及以上版本;
    两者的区别:

    Excel2003Excel2007
    后缀xlsxlsx
    结构二进制格式,其核心结构是符合文档类型的结构XML类型结构
    单sheet数据量行:65535 列:256行:1048576 列:16384
    特点存储容量有限基于xml压缩,占用空间小,操作效率高

    3.2 常见的Excel操作工具

    java中常用的用来操作Excel的工具有JXLPOI

    3.2.1 JXL

    JXL只能对Excel进行操作,属于比较老的框架,它只支持到Excel95-2000版本,现在已经停止和维护,所以不是重点学习的

    3.2.2 POI

    POI是apache的项目,可以对微软的Word,Excel,PPT进行操作,包括Office2003和2007,是目前主流的文档类操作框架。

    POI提供API给Java语言操作Excel的功能:

    3.2.3 API对象介绍

    1. 工作簿
      WorkBook(HSSFWordBook:2003版本;XSSFWordBook:2007及以上)
    2. 工作表
      Sheet (HSSFSheet:2003版本;XSSFSheet:2007及以上)

    3. Row (HSSFRow:2003版本;XSSFRow:2007及以上)
    4. 单元格
      Cell(HSSFCell:2003版本;XSSFCell:2007及以上)

    四、使用JXL操作Excel

    4.1 使用jxl导出基本知识点

    通过WritableWorkBookWritableSheetLabel这三个对象我们就可以实现Excel的到处工作。

    1、创建可写入的Excel工作簿

    // 创建一个流
    ServletOutputStream outputStream = response.getOutputStream();
    // 创建WorkBook
    WritableWorkbook workbook = Workbook.createWorkbook(outputStream);
    
    • 1
    • 2
    • 3
    • 4

    2、创建工作表

    // 创建一个工作表,并起了一个名字
    workbook.createSheet("一个Excel入门案例", 0);
    
    • 1
    • 2

    3、创建单元格
    添加文本类单元格
    【添加标题】

    /*思考表头是固定不变的,数据是变化的*/
    // 处理标题 列角标 行角标 内容
    String[] title = new String[] {"编号","姓名","入职日期","手机号","现住址"};
    // 创建标题列的Label
    Label label = null;
    for (int i = 0;i<title.length;i++) {
    	label = new Label(i,0,title[i]);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    【动态获取数据】

    // 查询所有用户的数据
    List<User> selectAll = userMapper.selectAll();
    for (int i = 0; i < selectAll.size(); i++) {
        // 编号
        label = new Label(0,i+1,selectAll.get(i).getId().toString());
        sheet.addCell(label);
    	// 姓名
    	label = new Label(1,i+1,selectAll.get(i).getUserName());
    	sheet.addCell(label);
    	// 电话
    	label = new Label(2,i+1,selectAll.get(i).getPhone());
    	sheet.addCell(label);			
    	// 入职时间
    	label = new Label(3,i+1,sdf.format(selectAll.get(i).getHireDate()));
    	sheet.addCell(label);			
    	// 现住址
    	label = new Label(4,i+1,selectAll.get(i).getAddress());
    	sheet.addCell(label);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4、写入到文件

    // 文件的导出一个流两个头(文件的打开放式 in-line浏览器直接打开;attachment附件形式下载打开、文件的下载是的mina类型)
    String filename = "一个JXL入门.xls";
    response.setHeader("content-disposition", "attachment;filename="+new String(filename.getBytes(),"ISO8859-1"));
        	
    response.setContentType("application/vnd.ms-excel");
    // 写出文件
    workbook.write();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    特别说明:不论是什么样的下载功能,都离不开一个口诀,那就是一个流两个头
    这里的一个流,必然指的是文件的输出流
    两个头:一个是响应的头信息必须为附件形式,注意如果以中文命名使用ISO8859-1编码保证不乱码;另外一个头是mina类型。

    5、释放资源

    // 释放资源
    workbook.close();
    outputSream.close();
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    补充知识:如何调整列宽?使用sheet的setColumnView(int col,int width)
    setColumnView(int col,int width):参数1:列号;参数2:列宽(源码x256***)

    // 创建一个工作表,并起了一个名字
    WritableSheet sheet = workbook.createSheet("一个Excel入门案例", 0);
    // 调整列宽 第一个参数是列号 第二个参数是宽度 只不过JXL会×256
    sheet.setColumnView(0, 5);
    sheet.setColumnView(1, 8);
    sheet.setColumnView(2, 15);
    sheet.setColumnView(3, 15);
    sheet.setColumnView(4, 30);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    TDengine 官网换了新“皮肤”,来看看这个风格是不是你的菜
    Java并发编程常见面试题
    ASfP: 增强AOSP平台开发的利器——Android Studio for Platform
    再有人说synchronized是重量级锁,就把这篇文章扔给他看
    【刷题笔记】之牛客面试必刷TOP101(1)
    人是AppSec的核心影响因素
    【Unity100个实用小技巧】如何修改UI上材质的Shader
    各大算法平台刷题数量统计网站
    java学习--day22(进程&线程)
    opencv4第二章
  • 原文地址:https://blog.csdn.net/mmklo/article/details/126674476