Java利用POI绘制表格

前提需求

最近公司要求写一些记录的表格,并且带有导出功能。再深入学习后,表格的底层其实就是list遍历塞值,导出功能的话可以由前端,后端实现,但技多不压身嘛,这里我自己就写了后端的导出功能,和大家分享一下。

代码实现

基础版:只有列的表头,没有合并单元格的情况。

效果如下:

示例代码实现:


    public void exportCureList(HttpServletResponse response,@RequestBody CureListRo ro) throws Exception{
        //查找需要填充的数据list
        List list=...;
        if (ObjectUtil.isEmpty(list)){
            throw new BusinessException("数据为空无法导出EXCEL");
        }
        List<List<Object>> rows = new ArrayList<>();
        //固定第一行表头
        List<Object> row = new ArrayList<>();
        row.add("患者姓名");
        row.add("手机号");
        row.add("门诊号");
        row.add("开单科室");
        row.add("开单医生");
        row.add("治疗师");
        row.add("治疗项目");
        row.add("是否签名");
        row.add("治疗开始");
        row.add("治疗完成");
        row.add("治疗项目");
        row.add("合计金额");
        rows.add(row);
        //填充剩余数据
        list.forEach(a->{
            List<Object> data= new ArrayList<>();
            data.add(a.getName());
            data.add(a.getPhone());
            data.add(a.getOutpatientId());
            data.add(a.getDepartmentName());
            data.add(a.getDoctor());
            data.add(a.getTherapists());
            data.add(a.getItems());
            data.add(a.getIsSign());
            data.add(a.getCureStartTime());
            data.add(a.getCureEndTime());
            data.add(a.getItems());
            data.add(a.getTotalPrice());
            rows.add(data);
        });
        //在内存操作,写到浏览器
        ExcelWriter writer= ExcelUtil.getWriter(true);
        //默认配置
        writer.write(rows,true);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("治疗记录", "UTF8") + ".xlsx");
        ServletOutputStream outputStream= response.getOutputStream();
        //将Writer刷新到OutPut
        writer.flush(outputStream,true);
        outputStream.close();
        writer.close();
    }

高阶版:表头存在斜杠,并且分层级有合并单元格。

示例代码实现:

public void exposeGetPerDepartmentOpenBillListNew(HttpServletResponse response,String startTime, String endTime, String departmentId, String doctorId, String tsName) throws IOException {
       //查询出的数据
        Vo vo=....;
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("sheetName");
        CellRangeAddress range = new CellRangeAddress(0, 1, 0, 0);
        sheet.addMergedRegion(range);
        sheet.setColumnWidth(0, 5000);
        Row row1 = sheet.createRow(0);
        row1.setHeight((short) 1000);
//画线(由左上到右下的斜线)  在A1的第一个cell(单位  分类)加入一条对角线
        Row row = sheet.getRow(0);
        Cell cell0 = row.createCell(0);
        cell0.setCellValue("开单医生    治疗项目");
        XSSFRow row2 = sheet.createRow(1);
        List<BuAchievementsHeaderVo> header = vo.getHeader();
        Map<String,Integer> indexMap =new HashMap<>();
        int index =0 ;
        for (BuAchievementsHeaderVo m:header){
            indexMap.put(m.getName(),index);
            index++;
        }
        for (int i = 0;i<header.size();i++){
            sheet.addMergedRegion(new CellRangeAddress(0, 0, i*3+1, i*3+3));
            row.createCell(i*3+1).setCellValue(header.get(i).getName());
            row2.createCell(i*3+1).setCellValue("开");
            row2.createCell(i*3+2).setCellValue("做");
            row2.createCell(i*3+3).setCellValue("剩");
        }
        CreationHelper helper = workbook.getCreationHelper();
        XSSFDrawing xssfDrawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = helper.createClientAnchor();
//设置斜线的开始位置,我这里是从第0行到第1行,从第0列到第1列
        anchor.setCol1(0);
        anchor.setCol2(1);
        anchor.setRow1(0);
        anchor.setRow2(2);
        XSSFSimpleShape simpleShape = xssfDrawing.createSimpleShape((XSSFClientAnchor) anchor);
//设置形状类型未线型
        simpleShape.setShapeType(ShapeTypes.LINE);
//设置线宽
        simpleShape.setLineWidth(0.5);
//设置线的风格
        simpleShape.setLineStyle(0);
//设置线的颜色
        simpleShape.setLineStyleColor(0,0,0);
//撒数据
        //int[] xys1 = { 112, 83 };
        //drawLine(sheet, row, 1, 3, 110, 83, xys1);
        List<BuAchievementsDataVo> data = vo.getData();
        for (int i = 0;i<data.size();i++){
            XSSFRow row3 = sheet.createRow(i + 2);
            row3.createCell(0).setCellValue(data.get(i).getDoctor());
            List<BuAchievementsItemVo> list = data.get(i).getList();
            for (int j = 0 ; j<list.size();j++){
                Integer ind = indexMap.get(list.get(j).getName());
                row3.createCell(ind*3+1).setCellValue(list.get(j).getCount().toString());
                row3.createCell(ind*3+2).setCellValue(list.get(j).getTreCount().toString());
                row3.createCell(ind*3+3).setCellValue(list.get(j).getSurCount().toString());
            }


        }

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("治疗记录", "UTF8") + ".xlsx");
        OutputStream outputStream= response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/671298.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【固定资产管理】软件系统建设方案体系文档(Word原件)

固定资产管理系统解决方案 1系统概述 1.1需求描述 1.2需求分析 1.3重难点分析 1.4重难点解决措施 2系统架构设计 2.1系统架构图 2.2关键技术 3系统功能设计 3.1功能清单列表 3.2资产采购 3.3资产验收 3.4资产入库 3.5资产领用 3.6资产出库 3.7资产维修 3.8资产…

【ARM-Linux篇】内核编译

一、Linux内核的主要功能 Linux内核的主要功能&#xff1a;进程管理、内存管理、驱动、系统调用 Linux操作系统框架 二、Linux内核编译流程 方法一&#xff1a; 1. 运行 build.sh 脚本&#xff0c; 记得加 sudo 权限 gyjgyj-virtual-machine:~/orangepi-build$ sudo ./buil…

如何跨渠道分析销售数据 - 7年制造业销售经验小结

如何跨渠道分析销售数据 - 7年制造业销售经验小结&#xff08;1&#xff09; 【前言】 在我过去7年销售工作生涯中&#xff0c;从第一年成为公司销冠后&#xff0c;我当时的确自满的一段时间&#xff0c;认为自己很了不起。但是第一年的销售业绩并没有拿到提成&#xff0c;最…

图解DSPy:Prompt的时代终结者?!

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…

OpenCASCADE开发指南<十四>:OCCT建模类之BRepPrimAPI_MakePipe创建管道

1、OpenCasCade拓扑几何 在Open CASCADE Technology (OCCT) 中,除了基本三维几何体建模类BRepBuilderAPI外,还提供了复杂模型的建模类,常用的有如下几种,他们可以单独使用或相互组合,通过OCCT提供的融合函数进行组装。例如:BRepOffsetAPI_ThruSections、BRepOffsetAPI_Ma…

Quick BI中lod_fixed函数数据计算过程解析

一、lod_fixed函数简介 lod_fixed{[声明维度1][,声明维度2]…&#xff1a;聚合表达式[:过滤条件]} [维度1][,维度2]...&#xff1a;声明维度&#xff0c;一方面如果外部筛选字段若不属于这里的声明维度则无效&#xff0c;另一方面这里声明的维度也内部聚合运算时的分组依据。使…

明日周刊-第12期

以前小时候最期待六一儿童节了&#xff0c;父母总会给你满足一个愿望&#xff0c;也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节&#xff0c;比如某些地区的小孩子&#xff0c;他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…

像艺术家一样工作:前言

名人名言 “艺术是盗窃” —— 巴勃罗毕加索 “不成熟的诗人模仿&#xff0c;成熟的诗人偷窃&#xff1b;对于偷窃得到的艺术&#xff0c;坏的诗人丑化它&#xff0c;好的诗人加入自己的理解&#xff0c;使它变得更好&#xff0c;至少会让它有点不同。最优秀的诗人&#xff0…

chat2-Client发送数据给Server

本文档描述了Client发送消息给Server&#xff0c; Server端打印接收的消息 一、Client 1.1.客户端的类Client.java中添加如下的start()方法 (表示启动客户端功能的方法)&#xff0c;并调用 /**start方法&#xff0c;作为客户端开始工作的方法*/ public void start(){ …

【SpringMVC】_SpringMVC实现用户登录

目录 1、需求分析 2、接口定义 2.1 校验接口 请求参数 响应数据 2.2 查询登录用户接口 请求参数 响应数据 4、服务器代码 5、前端代码 5.1 登录页面login.html 5.2 首页页面index.html 6、运行测试 1、需求分析 用户输入账号与密码&#xff0c;后端校验密码是否正确&a…

Python-3.12.0文档解读-内置函数sum()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 sum(iterable, /, start0) 参数&#xff1a; 返回值&#xff1a; 注意事…

【风力发电】山顶的白色“大风车”你了解吗?

文章目录 术语定义 基本要求 外部条件 电气系统 控制系统 参考资料 术语定义 风力发电机组wind turbine generator system;WTGS&#xff0c;将风的动能转换为电能的系统。示例如下&#xff1a; 支撑结构support structure&#xff0c;风力发电机组的塔架和基础部分。 机舱…

NVIDIA NeMo - 训练本地化多语种 LLM

本文转载自&#xff1a;使用 NVIDIA NeMo 训练本地化多语种 LLM &#xff08;2024年 5月 17日 By Nicole Luo and Amit Bleiweiss 第 1 部分 https://developer.nvidia.com/zh-cn/blog/training-localized-multilingual-llms-with-nvidia-nemo-part-1/ 第 2 部分 https://deve…

优盘打不开的困境与解决之道

在日常的工作和生活中&#xff0c;优盘作为一种便携式存储设备&#xff0c;因其小巧、轻便和容量大等特点而备受青睐。然而&#xff0c;当优盘突然无法打开时&#xff0c;我们往往会陷入一片混乱之中&#xff0c;担心存储在其中的重要数据会因此丢失。本文将详细解析优盘打不开…

服务器进不去conda环境问题

source ~/.bashrc 立即重新加载和应用 .bashrc 配置文件中的设置。当你对 .bashrc 文件进行了修改&#xff0c;比如添加或修改了环境变量、别名(alias)、函数等功能后&#xff0c;通常需要执行这个命令来让这些更改在当前终端会话中生效&#xff0c;而无需关闭并重新打开终端。…

牛客网刷题 | BC111 空心正方形图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

解决mysql5.7版本中,子查询order by后,对子查询进行group by分组获取最新记录无效的问题

目录 场景简介原因示例mysql5.7之前的版本mysql5.7之后的版本解决1、使用having2、使用limit3、使用子查询获取目标数据ID 场景简介 子查询order by后&#xff0c;对子查询进行group by分组获取最新记录失败 应用场景&#xff1a;一对多的关系&#xff0c;通常需要取最新、最…

牛客网刷题 | BC107 箭形图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

IO流(2)

缓冲流 字节缓冲流 利用字节缓冲区拷贝文件&#xff0c;一次读取一个字节&#xff1a; public class test {public static void main(String [] args) throws IOException {//利用字节缓冲区来拷贝文件BufferedInputStream bisnew BufferedInputStream(new FileInputStream(&…