文档章节

利用poi进行数据的excel导出

李阳-kevin
 李阳-kevin
发布于 2017/07/24 10:23
字数 1382
阅读 64
收藏 0

添加maven依赖:

<!-- poi --> 
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17-beta1</version>
</dependency>

<!-- fast json -->
<dependency> 
    <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.31</version>
</dependency>

主要代码:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.liyang.entity.UserEntity;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 导出excel工具
 *
 * @author 李阳
 * @mail ly_triangle@126.com
 * 15002992382
 * 2017-07-24
 */
public class ExcelUtil {

    /**
     * 根据给定的数据在前端页面导出excel
     *
     * @param fileName 文件名
 * @param wb 工作簿
     * @param response
     * @throws IOException
     */
    public static void exportDatasExcel(String fileName, Workbook wb, HttpServletResponse response) 
        throws IOException {

         //清空前端缓存  
        response.reset(); 

        //指定前端文件mime类型  
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + new String(replaceSpecialChars(fileName).getBytes(), "iso8859-1")
                + ".xlsx");

        //字节数组输出流
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        //将工作簿写进字节数组输出流中
        wb.write(out);

        //创建字节数组输入流,将输出流中的数据写进该输入流中,最后创建输入流的缓冲流,便于读取数据
        BufferedInputStream bufferIn = new BufferedInputStream(new ByteArrayInputStream(out.toByteArray()));

        //获得response输出流,并获得输出流的缓冲流,便于写入数据
        BufferedOutputStream bufferOut = new BufferedOutputStream(response.getOutputStream());

        //每次输出文件1000字节长度数据到输出流
        byte[] buffer = new byte[1000];
        int bytesRead;

        //读取输入缓冲流中的数据,经过缓冲输出流发送给前端下载
        while (-1 != (bytesRead = bufferIn.read(buffer))) {
            bufferOut.write(buffer, 0, bytesRead);
        }

        bufferOut.flush();
        bufferIn.close();
        bufferOut.close();
    }

    /**
     * 创建excel表格(记录性结果)
     *
     * @param titles  标题集合
     * @param keys    key值集合,用于读取json对象中的数据
     * @param objects 数据对象集合
     * @return
     */
    private static Workbook buildWorkbook(List<String> titles, List<String> keys, List<Object> objects, String fileName) {
        //创建工作簿
        Workbook wb = new XSSFWorkbook();  //or new HSSFWorkbook();

        //创建表格
        Sheet sheet = wb.createSheet(replaceSpecialChars(fileName));

        //第一行
        Row row = sheet.createRow(0);

        //第二行
        Row row1 = sheet.createRow(1);

        //创建数据单元格样式       
        CellStyle style = creatStyle(wb);

        //创建标题单元格样式
        CellStyle titleStyle = creatTitleStyle(wb);
        Cell cell;
        Cell cell1;

        //遍历标题,标题占两行
        for (int t = 0; t < titles.size(); t++) {

            //创建标题单元格并设置标题单元格的值
            cell = row.createCell(t);
            cell.setCellValue(titles.get(t));

            //创建第二行单元格
            cell1 = row1.createCell(t);

            //合并上下单元格(标题占两行)
            sheet.addMergedRegion(new CellRangeAddress(0, 1, t, t));

            //对单元格使用样式
            cell.setCellStyle(titleStyle );
            cell1.setCellStyle(titleStyle );
        }

        //将对象集合转换成json对象数组
        JSONArray array = JSON.parseArray(JSON.toJSONString(objects));

        //遍历json对象数组,将数据写进excel        for (int r = 2; r < array.size() + 2; r++) {
            JSONObject o = array.getJSONObject(r - 2);

            //创建行
            row = sheet.createRow(r);

            //创建行单元格,并赋值
            for (int c = 0; c < keys.size(); c++) {
                String value = o.get(keys.get(c)) == null ? "" : o.get(keys.get(c)).toString();
                cell = row.createCell(c);
                cell.setCellValue(value);
                cell.setCellStyle(style);
            }
        }

        // 最后一列宽自适应
        sheet.autoSizeColumn(titles.size()-1);

        //获得工作簿
        return wb;
    }

创建复杂excel表格(非记录性数据,需要一定模板):

/**
 * 动态生成复杂excel
 *
 * @param rowSize    行数
 * @param columnSize 列数
 * @param models     单元格实例集合(每一个单元格(包括合并的单元格)起止行列四个索引和单元格的值)
 * @param fileName   文件名
 * @return
 */
public static Workbook buildWorkbook2(Integer rowSize, Integer columnSize, List<CellModel> models, String fileName) {
    Workbook wb = new XSSFWorkbook();
    Sheet sheet = wb.createSheet(replaceSpecialChars(fileName));
    CellStyle style = creatStyle(wb);
    CellStyle titleStyle = creatTitleStyle(wb);
    Row row;
    Cell cell;

    //创建空表格
    for (int r = 0; r < rowSize; r++) {
        row = sheet.createRow(r);
        for (int c = 0; c < columnSize; c++) {
            cell = row.createCell(c);
            if (0 == r || 1 == r) {
                cell.setCellStyle(titleStyle);
            } else {
                cell.setCellStyle(style);
            }
        }
    }

    //单元格赋值并合并单元格
    models.forEach(c -> {
        Integer rowBegin = c.getRowBegin();
        Integer rowEnd = c.getRowEnd();
        Integer columnBegin = c.getColumnBegin();
        Integer columnEnd = c.getColumnEnd();
        sheet.getRow(rowBegin).getCell(columnBegin).setCellValue(c.getValue().toString());
        if (rowBegin.intValue() != rowEnd.intValue() || columnBegin.intValue() != columnEnd.intValue())
            sheet.addMergedRegion(new CellRangeAddress(rowBegin, rowEnd, columnBegin, columnEnd));
    });

    short height = sheet.getDefaultRowHeight();
    sheet.setDefaultRowHeight((short) (height * 1.7));
    sheet.setDefaultColumnWidth(15);

    return wb;
}

单元格对象:

public class CellModel {
    private Object value = ""; //单元格值
    private Integer rowBegin; //开始行索引
    private Integer rowEnd;  //结束行索引
    private Integer columnBegin;  //开始列索引
    private Integer columnEnd;  //结束列索引
    .
    .
    .
    .
    .
    略

创建标题样式:

/**
 * create title style
 * @param wb
 * @return
 */
private static CellStyle creatTitleStyle(Workbook wb) {
    Font font = wb.createFont();
    font.setFontHeightInPoints((short) 12);
    font.setFontName("黑体");
    font.setBold(true);

    CellStyle titleStyle = wb.createCellStyle();
    titleStyle.setAlignment(HorizontalAlignment.CENTER);
    titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    titleStyle.setBorderTop(BorderStyle.THIN);
    titleStyle.setBorderBottom(BorderStyle.THIN);
    titleStyle.setBorderLeft(BorderStyle.THIN);
    titleStyle.setBorderRight(BorderStyle.THIN);

    //背景色
    titleStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SEA_GREEN.getIndex());
    titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    titleStyle.setFont(font);

    return titleStyle;
}

创建数据样式:

private static CellStyle creatStyle(Workbook wb) {
    Font font = wb.createFont();

    //字号
    font.setFontHeightInPoints((short) 12);

    //字体
    font.setFontName("宋体");

    //斜体
    //font.setItalic(true);

    //加粗
    //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

    //创建样式
    CellStyle style = wb.createCellStyle();

    // 给样式指定字体
    style.setFont(font);

    //纵横向居中
    style.setAlignment(HorizontalAlignment.CENTER);
    style.setVerticalAlignment(VerticalAlignment.CENTER);

    //四周边框
    style.setBorderTop(BorderStyle.THIN);
    style.setBorderBottom(BorderStyle.THIN);
    style.setBorderLeft(BorderStyle.THIN);
    style.setBorderRight(BorderStyle.THIN);

    return style;
}

文件名特殊字符处理(特殊字符统一用空格替换)

private static String replaceSpecialChars(String fileName) {
    return fileName
            .replaceAll(":", " ")
            .replaceAll(":", " ")
            .replaceAll("?", " ")
            .replaceAll("\\?", " ")
            .replaceAll("\\*", " ")
            .replaceAll("]", " ")
            .replaceAll("\\[", " ")
            .replaceAll("“", " ")
            .replaceAll("”", " ")
            .replaceAll("\"", " ")
            .replaceAll("\\|", " ")
            .replaceAll(">", " ")
            .replaceAll("<", " ")
            .replaceAll("\\\\", " ")
            .replaceAll("/", " ");
}

测试1(记录性结果):

/**
     * test
     */
    public static void main(String[] args) throws IOException {

        //构造数据对象集合
        List list = Arrays.asList(new UserEntity("kevin", "lee", 5),
                new UserEntity("david", "lee", null),
                new UserEntity("kavin", "", 6),
                new UserEntity("kavein", "lee", 65));

        //构造标题和key值列表,生成工作簿
        Workbook wb = buildWorkbook(Arrays.asList("姓名", "全名", "年龄"),
                Arrays.asList("stageName", "fullName", "sex"), list);

        //生成服务器本地文件,如需输出到前端,只需要调用exportDatasExcel方法即可
        FileOutputStream fileOut = new FileOutputStream("dataExcel.xlsx");
        wb.write(fileOut);
        fileOut.close();
        wb.close();
    }

测试2(复杂结果):

public static void main(String[] args) throws IOException {

    //构造数据对象集合
    List list = new ArrayList();
    list.add(new CellModel("标题", 0, 1, 0, 3));
    list.add(new CellModel("购买渠道", 2, 26, 0, 0));
    list.add(new CellModel("微信", 2, 13, 1, 1));
    list.add(new CellModel("网站", 14, 26, 1, 1));
    list.add(new CellModel("微信平台名称", 2, 3, 2, 3));
    list.add(new CellModel("大秦帝国", 4, 13, 2, 3));
    list.add(new CellModel("网站平台名称", 14, 15, 2, 3));
    list.add(new CellModel("饿狼传说", 16, 26, 2, 3));

    //构造标题和key值列表,生成工作簿
    Workbook wb = buildWorkbook2(27, 5, list, "domo");

    //生成服务器本地文件,如需输出到前端,只需要调用exportDatasExcel方法即可
    FileOutputStream fileOut = new FileOutputStream("domo.xlsx");
    wb.write(fileOut);
    fileOut.close();
    wb.close();
}

测试结果:

记录性结果excel:

复杂excel结果:

 

© 著作权归作者所有

共有 人打赏支持
李阳-kevin
粉丝 4
博文 98
码字总数 42467
作品 0
西安
程序员
[转]Java大数据量导出Excel的问题

试共同条件: 数据总数为110011条,每条数据条数为19个字段。 电脑配置为:P4 2.67GHz,1G内存。 一、POI、JXL、FastExcel比较 POI、JXL、FastExcel均为java第三方开源导出Excel的开源项目。...

大冬
2011/07/28
0
1
JavaScript与Excel灵活交互制作Web报表

【IT168 技术】Web报表的开发是一个比较常见的功能,然而在B/S构件上实现这些功能并没有在C/S构架上那些简单,针对这样的问题,本篇文章提供相应的解决方案,在下面的内容中将介绍JS与Excel...

天极网
2012/03/01
0
0
Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框

在web开发中,有一个经典的功能,就是数据的导入导出。特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作。而数据导出的格式一般是EXCEL或者...

MiniBu
2015/04/08
0
0
Java程序员从笨鸟到菜鸟之(一百零四)java操作office和pdf文件(二)利用POI实现数据导出excel报表

在上一篇博客中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式。不仅仅简单的读取office中的数据.尤其是在生产管理...

长平狐
2012/11/12
1K
0
Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框

在web开发中,有一个经典的功能,就是数据的导入导出。特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作。而数据导出的格式一般是EXCEL或者...

文文1
2015/12/02
914
0

没有更多内容

加载失败,请刷新页面

加载更多

秒杀网站系统设计详解

最近总有一些朋友问高并发问题,后来就想自己把一个秒杀系统作为例子详细分解一下,也是一个学习过程。 首先假设场景,预计该活动可能有1万人参加,那最大并发数为1万。 主要面对的问题分析:...

小海bug
13分钟前
0
0
TypeScript基础入门之装饰器(一)

转发 TypeScript基础入门之装饰器(一) 介绍 随着TypeScript和ES6中Classes的引入,现在存在某些场景需要额外的功能来支持注释或修改类和类成员。 装饰器提供了一种为类声明和成员添加注释和元...

durban
23分钟前
0
0
sed命令扩展使用操作

打印某行到某行之间的内容 假若文件test.txt的内容是: ertfff**[abcfd]123324444[rty]**fgfgf 怎么能截取 [abcfd]123324444[rty] 这一部分出来呢? 操作命令: 知道开始行和结...

野雪球
39分钟前
1
0
JVM内存笔记

Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓 冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。 Java 线程结束,原...

凌渡
45分钟前
1
0
284. Peeking Iterator

Description Tag: Design Difficulties: Medium Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the pee......

52iSilence7
47分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部