开发应用软件经常需要将界面上表格中的数据导出到excel报表,方便用户查看分析。一般来说用户对报表有一定的格式要求,我们常用的做法时先手工制作好报表模板,导出数据前先拷贝一份模板文件,再往文件中写数据。
完整的流程是这样的:
- 用户执行导出报表操作。
- 系统拷贝一份安装时内置的报表模板。
- 往拷贝的模板文件中写入数据。
- 上传文件到文件服务器。
- 前端从文件服务器下载文件。
考虑到有些文件比较大的话,上传前可以先压缩成zip包格式,下载也下载zip包。
不同的系统提供的文件上传下载接口不一样,差别不打。下面给出通过POI接口写入数据到excel的样例代码。
依赖的第三方包
写数据到excel公共方法封装
package com.github;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* Excel写数据公共方法封装类
* @author elon
* @version 2018年12月20日
*/
public class ExcelUtility
{
private String filePath = "";
private XSSFWorkbook workBook = null;
private SXSSFWorkbook sworkBook = null;
private Sheet curSheet = null;
public ExcelUtility(String filePath)
{
this.filePath = filePath;
}
/**
* 打开待读取/写入的Excel文件
* @throws FileNotFoundException
*/
private void openExcel() throws FileNotFoundException
{
FileInputStream inFile = new FileInputStream(filePath);
try
{
workBook = new XSSFWorkbook(inFile);
sworkBook = new SXSSFWorkbook(workBook, 100);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
inFile.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
* 选择指定的Sheet页,作为输入/读取。
* @param sheetId sheet唯一标示。名称或者索引
* @return true:获取成功;false:获取失败
*/
private <T> boolean selectSheet(T sheetId)
{
if (sheetId instanceof String)
{
curSheet = sworkBook.getSheet(sheetId.toString());
return true;
}
else if (sheetId instanceof Integer)
{
curSheet = sworkBook.getSheetAt(((Integer) sheetId).intValue());
return true;
}
else
{
return false;
}
}
/**
* 往excel中批量写入数据
* @param sheetNo sheet页编号,从1开始
* @param startRow 开始写数据的起始行
* @param dataList 数据列表
* @return true-写入成功; false-写入失败
* @throws FileNotFoundException
*/
public <T> boolean writeDatas(int sheetNo, int startRow, List<List<T>> dataList) throws FileNotFoundException {
//1、打开excel文件
openExcel();
//2、选择写入数据的sheet页
boolean result = selectSheet(sheetNo);
if (result == false) {
return result;
}
//3、逐行写入数据
for(List<T> data : dataList) {
writeSingleRowData(startRow++, data);
}
//4、保存文件,关闭流
saveExcel();
return true;
}
/**
* 写一行数据到Excel中
* @param rowNum 行号
* @param valueList 一行内容
* @return true:写成功; false:写失败
*/
private <T> boolean writeSingleRowData(int rowNum, List<T> valueList)
{
Row row = curSheet.getRow(rowNum);
if (row == null)
{
row = curSheet.createRow(rowNum);
}
if (row == null)
{
return false;
}
for (int cellNum = 0; cellNum < valueList.size(); ++cellNum)
{
Cell cell = row.getCell(cellNum);
if (cell == null)
{
cell = row.createCell(cellNum);
}
if (cell == null)
{
continue;
}
T value = valueList.get(cellNum);
cell.setCellValue(String.valueOf(value));
}
return true;
}
/**
* 保存数据到Excel文件
* @throws FileNotFoundException
*/
private void saveExcel() throws FileNotFoundException
{
FileOutputStream out = new FileOutputStream(filePath);
try
{
sworkBook.write(out);
out.flush();
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
sworkBook.dispose();
}
}
接口调用样例代码
package com.github;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class TestMain
{
public static void main(String[] args)
{
ExcelUtility excel = new ExcelUtility("E:/temp/test.xlsx");
List<Object> datas = new ArrayList<Object>();
for (int colum = 0; colum < 15; ++colum)
{
datas.add("123");
datas.add(456);
}
List<List<Object>> dataList = new ArrayList<>();
for (int row = 0; row < 500000; ++row)
{
dataList.add(datas);
}
try
{
excel.writeDatas(0, 1, dataList);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
System.out.println("写入数据完成!");
}
}