日志

SXSSFWorkbook的简单使用

 来源    2020-05-23    1  

在工作中使用到SXSSFWorkbook来导出Excel,写一篇博客记录一下SXSSFWorkbook的使用方法

1.介绍

SXSSFWorkbook是属于apache基金会的Excel导出工具类,从其官网上可以看出SXSSFWorkbook实现了Workbook接口
Streaming version of XSSFWorkbook implementing the "BigGridDemo" strategy. 
This allows to write very large files without running out of memory as 
only a configurable portion of the rows are kept in memory at any one time.
SXSSFWorkbook是实现“BigGridDemo”策略的XSSFWorkbook的流媒体版本。SXSSFWorkbook允许编写非常大的文件而不会耗尽内存,
因为在任何时候,只有可配置的一部分行保存在内存中。

2.使用

 首先我们定义一个列的实体类,包含列的名称,样式等

import org.apache.poi.ss.usermodel.CellStyle;

/**
 * @describe 定义excel列
 *
 */
public class ExcelColumnInfo {
    private String columnName;
    private String columnCode;
    /**
     * 单元格样式
     */
    private CellStyle cellStyle;
    }
    
    public ExcelColumnInfo(String columnName, String columnCode) {
        super();
        this.columnName = columnName;
        this.columnCode = columnCode;
    }
    
    public ExcelColumnInfo(String columnName, String columnCode, CellStyle cellStyle) {
        super();
        this.columnName = columnName;
        this.columnCode = columnCode;
        this.cellStyle = cellStyle;
    }
    
    public String getColumnName() {
        return columnName;
    }
    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }
    public String getColumnCode() {
        return columnCode;
    }
    public void setColumnCode(String columnCode) {
        this.columnCode = columnCode;
    }
    
    public CellStyle getCellStyle() {
        return cellStyle;
    }

    public void setCellStyle(CellStyle cellStyle) {
        this.cellStyle = cellStyle;
    }

}

再定义一个Excel写入单元格数据的工具类

/**
 * Excel辅助类
 */
public class ExcelUtil {

    public static void setCell(Cell cell, Object obj) {
        if (obj == null) {
            cell.setCellValue("");
        } else if (obj instanceof Integer) {
            cell.setCellValue((int) obj);
        } else if (obj instanceof BigDecimal) {
            cell.setCellValue(((BigDecimal) obj).doubleValue());
        } else if (obj instanceof String) {
            cell.setCellValue((String) obj);
        } else if (obj instanceof Double) {
            cell.setCellValue((double) obj);
        } else if (obj instanceof Long) {
            cell.setCellValue((long) obj);
        }
    }

    public static void setCell(Cell cell, Object obj, CellStyle cellStyle) {
        cell.setCellStyle(cellStyle);
        if (obj instanceof Integer) {
            cell.setCellValue((int) obj);
        } else if (obj instanceof BigDecimal) {
            cell.setCellValue(((BigDecimal) obj).doubleValue());
        } else if (obj instanceof String) {
            cell.setCellValue((String) obj);
        } else if (obj instanceof Double) {
            cell.setCellValue((double) obj);
        } else if (obj instanceof Long) {
            cell.setCellValue((long) obj);
        } else {
            cell.setCellValue("");
        }
    }
}

然后开始写导出的方法

@Service
public class ExportSystemLogService{

    @Autowired
    private SystemLogMapper mapper;

    public SXSSFWorkbook exportExcel(Map<String, Object> params) throws IOException {
        
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        //获取表格列信息
        LinkedHashMap<String, List<ExcelColumnInfo>> excelInfo = getExcelInfo(wb);
        for(String sheetName : excelInfo.keySet()){
            //创建sheet页
            Sheet sheet = wb.createSheet(sheetName);
            //获取该sheet页的列信息
            List<ExcelColumnInfo> excelColumnInfo = excelInfo.get(sheetName);
            //生成Excel数据
            generateExcelData(sheet,excelColumnInfo,params);
        }
        return wb;
    }

    protected LinkedHashMap<String, List<ExcelColumnInfo>> getExcelInfo(Workbook wb) {
        LinkedHashMap<String, List<ExcelColumnInfo>> excelInfo = new LinkedHashMap<>();
        List<ExcelColumnInfo> columns = new ArrayList<>();
        CellStyle percentCellStyle = wb.createCellStyle();
        //CellStyle wrapStyle = wb.createCellStyle();
        //wrapStyle.setWrapText(true);    //设置自动换行

        columns.add(new ExcelColumnInfo("日志编号", "LOG_ID"));    //后面的columnCode与从数据库中查询出来的字段名一致
        columns.add(new ExcelColumnInfo("操作时间", "CREATE_TIME"));
        columns.add(new ExcelColumnInfo("操作人", "CREATE_USER"));
        columns.add(new ExcelColumnInfo("操作模块", "OPERATION_MODULE"));
        columns.add(new ExcelColumnInfo("操作类型", "OPERATION_TYPE"));
        columns.add(new ExcelColumnInfo("详情", "OPERATION_DETAIL"));
        columns.add(new ExcelColumnInfo("日志级别", "LOG_LEVEL"));
        columns.add(new ExcelColumnInfo("备注", "REMARK"));

        excelInfo.put("系统日志", columns);
        return excelInfo;
    }

    private void generateExcelData(Sheet sheet,List<ExcelColumnInfo> excelColumnInfo,Map<String, Object> params) {
        //设置列的宽度,第一个参数为列的序号,从0开始,第二参数为列宽,单位1/256个字节
        sheet.setColumnWidth(0, 12*256);
        sheet.setColumnWidth(2, 16*256);
        sheet.setColumnWidth(5, 12*256);
        sheet.setColumnWidth(6, 26*256);
        sheet.setColumnWidth(7, 26*256);
        //设置开始行和开始列
        int rowIndex = 0;
        int columnIndex = 0;
        Row row = sheet.createRow(rowIndex);
        //创建表头
        for (ExcelColumnInfo column : excelColumnInfo) {
            ExcelUtil.setCell(row.createCell(columnIndex++), column.getColumnName());
        }
        //获取导出数据
        List<HashMap<String, Object>> data = mapper.getSystemLog(params);
        rowIndex = 1;
        for (HashMap<String, Object> tmp : data) {
            Row row1 = sheet.createRow(rowIndex);
            columnIndex = 0;
            for(ExcelColumnInfo column : excelColumnInfo){
                Cell cell = row1.createCell(columnIndex);
                //设置单元格样式
                if (column.getCellStyle() != null) {
                    cell.setCellStyle(column.getCellStyle());
                }
                ExcelUtil.setCell(cell,tmp.get(column.getColumnCode()));
                columnIndex++;
            }
            rowIndex++;
        }
    }
}

其中Mapper接口与xml文件配置如下

@Mapper
@Repository
public interface SystemLogMapper {

    List<HashMap<String, Object>> getSystemLog(@Param("params") Map<String, Object> params);

}
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.XXX.XXX.SystemLogMapper">
    
    <select parameterType="java.util.HashMap" resultType="java.util.HashMap">
        SELECT 
        LOG_ID,
        CREATE_TIME,
        CREATE_USER,
        OPERATION_MODULE,
        OPERATION_TYPE,
        OPERATION_DETAIL,
        LOG_LEVEL,
        REMARK
        FORM SYSTEM_LOG
        ORDER BY CREATE_TIME DESC
    </select>
</mapper>

在调用时,只需在Controller层调用ExportSystemLogService.exportExcel(params)方法即可。

相关文章
一个简单的文件目录选择器 – FileListerDialog
日志FileListerDialog FileListerDialog helps you to list and pick file/directory. Library is built for An ...
1
最简单的gui工具包,用于学习和使用java
问答我想学习java的GUI开发.任何人都可以推荐一些易于学习和使用GUI小部件工具包.我还想知道一个优秀的工具包GUI设计师.该工具包应该与gtk和qt很好地集成.提前致谢!::好吧,我真的不知道为什么 ...
2
Visual Studio代码:如何自动执行简单的正则表达式查找和替换?
问答我尝试在Visual Studio代码中创建一个简单的正则表达式查找和替换任务. 目前我从AD一些用户复制到Visual Studio代码中的临时文件,并删除行开头的"CN ="和 ...
1
shell – 在ksh中使用typeset与简单设置变量之间有什么区别吗?
问答以下2行完全相同吗?如果不是有什么区别?我已经看到很多shell脚本使用1号,只是想知道它与2号相比你给了你什么. > typeset TARGET ="${XMS_HOME} / c ...
2
yocto – 简单安装本机脚本以用于其他配方
问答我需要在一个配方(foo-native)中安装一个本机脚本,称之为foo,然后在另一个(目标)配方的do_compile步骤中使用它 – 调用它吧. 我的(最小)原生食谱 SRC_URI = &quo ...
python – 从数据帧返回仅位置值的最简单方法
问答这是一个非常简单的问题,但我总是发现自己做了太多的操作来从数据帧中获取单个位置值.让我解释: import pandas as pd df = pd.DataFrame(list(zip('abcde ...
1
数学 – 看起来像一个简单的图形问题
问答目前我有一个控件,我需要添加设施来应用各种锐度(或灵敏度).这个问题最好用图片说明: Graph http://img87.imageshack.us/img87/7886/control.png 正 ...
jboss5.x – 有一种简单的方法来创建一个新的Wildfly服务器实例
问答有没有一种简单的方法来创建一个新的Wildfly服务器实例. 在JBoss AS5中你所要做的就是创建一个默认或全部的副本并启动jboss: run.sh -c [New instance name] ...
1
c – 为“简单对话”创建视图的方法
问答关于在创建GUI时将视图与逻辑分离的问题,我有一堆问题要发布. 以下是我将使用"简单对话"方法为具有标签和按钮的简单对话框所做的最小示例.按下按钮应在标签上显示一些文字.我使用的是 ...
1
(Java中的线程池)增加线程数会导致简单的for循环减慢速度.为什么?
问答我有一些可以轻松并行化的工作,我想使用Java线程将工作分散到我的四核机器上.这是一种应用于旅行商问题的遗传算法.它听起来不容易并行化,但第一个循环非常容易.我谈论实际演变的第二部分可能是也可能不是, ...
1
c – 如何为返回二进制数据的简单C函数实现单元测试?
问答我想为一个应该压缩或解压缩某些数据的函数实现一些非常简单的C/C++单元测试. 主要是输入是二进制块,输出也是二进制块.二进制块应少于50个字节,可能有5-6对. 我正在寻找一个最好不需要第三方库的解 ...
汇编 – 简单mips中的无限循环
问答我正在尝试学习$ra,所以我想要的输出是"mainfunction1main",主要调用function1,function1返回main,主要完成.但由于某种原因,我得到一个无限 ...
1
c# – Linq简单查询改进
问答我是Linq查询的初学者,我想知道我的查询是否可以通过另一种方式改进: long vehid = json.VehicleId.Value; DateTime date = DateTime.Pars ...
1
jQuery / PHP邮件发送简单方法?
问答好吧,长话短说: JavaScript的: jQuery("submit").click(function() { var address = jQuery("#mail ...
ubuntu – 从Docker容器发送邮件的简单方法?
问答我有一个在Docker容器内运行的备份脚本,我希望它在磁盘使用率低时向我发送电子邮件. 这是脚本: #!/bin/bash CURRENT=$(df /data | grep / | awk '{ p ...
1
简单的docker容器:构建专用映像或mount配置为卷?
问答我正在组装一个docker-compose.yml文件来为我正在处理的项目运行多个服务.该项目有一个Magento和Wordpress网站,位于同一个域下,"同一域"方面需要一个非 ...
1
node.js – 通过Jenkins CI在Docker容器中运行Selenium测试的最简单方法
问答我想用Dockers容器中的Jenkins CI执行我的自动化测试,用Nightwatch-Cucumber编写.我有一个Docker图像,我想用它. 这就是我想要做的更详细的事情. >开始对J ...
1
apache – 简单的.htaccess子域重写
问答我知道这里有很多关于这个的问题--但是现在我感觉被迎面而来的车头灯震惊了--我只是不知道从哪里开始以及选择哪个选项. 我的要求很简单. 用户转到http://application.domain.co ...
1
无法在Erlang中生成一个简单的服务器
问答我有一个简单的服务器: -module(simple_server). -export([loop/0]). loop() -> receive {fact, N, Sender} -> ...
apache-2.2 – 如何使用fastcgi和简单的测试脚本设置apache?
问答我想在Kubuntu服务器上用apache设置fastcgi已经有好几天了.尽管到处搜寻,但我无法让它发挥作用.如果我尝试使用cgi应用程序运行该站点,则apache挂起并在超时后返回500错误. 这 ...