目前, java导出exexl目前有两种方法,第一种是基于jxl,jar的导出,第二种是基于Apache的pio的方式。
首先,我们先讨论一下execl的格式背景
| execl版本 | 最多行 | 最多列 |
| 2003 | 65536(2^16) | 256(2^8) |
| 2007(及以上版本) | 1048576(2^20) | 16384(2^14) |
第一步导入所需要的jar包

第一种,jar包较为久远jxl 版本的数据,很可惜这个只支持2003版本的execl
具体数据我本人都是存在Arrylist中,
//创建文件,获取数据,写入excel
// 参数一:数据list
//参数二:execl的列名,说白了就是一行数据每列的名称,存在数组里面,
//参数三:输出文件的路径位置
public void writeExcel(List<String[]> list,String[] title,String path) {
String fileName =path;
Label label;
//首先要使用Workbook类的工厂方法创建一个可写入的工作薄(Workbook)对象
try {
WritableWorkbook wwb = Workbook.createWorkbook(new File(fileName));
File dbfFile = new File(fileName);
if (!dbfFile.exists() || dbfFile.isDirectory()) {
dbfFile.createNewFile();
}
int sheets=3;//创建多少个sheet
//写入数据
for(int i=0;i<sheets;i++) {
WritableSheet ws = wwb.createSheet("列表" + (i + 1), i); //创建一个可写入的工作表
if(title.length>256){
System.out.println("......."+title.length);
System.out.println("加入前"+ws.getColumns());
ws.insertColumn((title.length-256));
System.out.println("加入后"+ws.getColumns());
}
//添加表头
for(int j=0;j<title.length;j++) {
label = new Label(j, 0, title[j], getHeader());
ws.addCell(label);
}
//设置单元格属性
WritableCellFormat wc = new WritableCellFormat();
// 设置居中
wc.setAlignment(Alignment.RIGHT);
// 设置边框线
wc.setBorder(Border.ALL, BorderLineStyle.THIN);
int num =(int)(i * maxRow);
int index = 0;
for (int m = num; m <list.size(); m++) {
if (index == maxRow) {//判断index == mus的时候跳出当前for循环
break;
}
String[] arrData = list.get(m);
for (int k = 0; k < arrData.length; k++) {
ws.setColumnView(k, 20);
//System.out.println("arrData=>"+k+"="+arrData[k]);
//new Label(0, 0, "This is a Label cell",wcfF);
//第一个是代表列数, 第二是代表行数,第三个代表要写入的内容,第四个是可选项,是输入这个label里面的样式
ws.addCell(new Label(k, index+1, arrData[k]));
}
index++;
}
}
wwb.write();//从内存中写入文件中
System.gc();
wwb.close();//关闭资源,释放内存
} catch (Exception e) {
e.printStackTrace();
}
}
//设置表头
public static WritableCellFormat getHeader() {
// 定义字体
WritableFont font = new WritableFont(WritableFont.TIMES, 10,
WritableFont.BOLD);
try {
// 黑色字体
font.setColour(jxl.format.Colour.BLACK);
} catch (WriteException e1) {
e1.printStackTrace();
}
WritableCellFormat format = new WritableCellFormat(font);
try {
// 左右居中
format.setAlignment(jxl.format.Alignment.CENTRE);
// 上下居中
format.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
// 黑色边框
format.setBorder(Border.ALL, BorderLineStyle.THIN, jxl.format.Colour.BLACK);
// 黄色背景
format.setBackground(jxl.format.Colour.YELLOW);
} catch (WriteException e) {
e.printStackTrace();
}
return format;
}
第二种模式 通过pio模式导出数据,这种里面支持数据库表列数据超过256列
/// 参数1,数据list
/// 参数2 execl头文件数组
/// 参数3 execl文件位置
public void WriteExeclFilePio(List<String[]> list,String[] title,String path) {
try {
File dbfFile = new File(path);
if (!dbfFile.exists() || dbfFile.isDirectory()) {
dbfFile.createNewFile();
}
FileOutputStream out = new FileOutputStream(dbfFile);
SXSSFWorkbook wb=new SXSSFWorkbook (); // 定义一个新的工作簿
SXSSFSheet sheet = wb.createSheet("列表1");
for (int k = 0; k < list.size(); k++) {
SXSSFRow rows=sheet.createRow(k);
for (int j = 0; j <title.length; j++) {
SXSSFCell cell;
if(k==0){
//sheet.trackAllColumnsForAutoSizing();
cell=rows.createCell(j); //加载标题数据
cell.setCellValue(title[j]);
}else{
cell=rows.createCell(j); //加载数据
cell.setCellValue(list.get(k)[j]);
// System.out.printf("%S",list.get(k)[j]+" ");
}
// sheet.trackAllColumnsForAutoSizing();
// sheet.autoSizeColumn(j);
}
// System.out.println();
}
sheet.trackAllColumnsForAutoSizing();
wb.write(out);
out.close();
//wb.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
这种可以导出07版及以上execl文件,但是存在一个内存泄漏的问题,由于电脑内存不够,jvm抛出异常,这种是jvm开拓了增加90%的内存,但是内存数据仍然只写了10%,导致虚拟机抛出异常,在查看文档后发现SXSSFWorkbook类中存在一个构造函数SXSSFWorkbook(int rows),这里的参数是表示java虚拟机内心最多缓存多少行数据,当达到这个值的时候,数据就想队列一样往硬盘写数据。

pio完整代码:
/// 参数1,数据list
/// 参数2 execl头文件数组
/// 参数3 execl文件位置
public void WriteExeclFilePio(List<String[]> list,String[] title,String path) {
try {
File dbfFile = new File(path);
if (!dbfFile.exists() || dbfFile.isDirectory()) {
dbfFile.createNewFile();
}
FileOutputStream out = new FileOutputStream(dbfFile);
SXSSFWorkbook wb=new SXSSFWorkbook (1000); // 定义一个新的工作簿
SXSSFSheet sheet = wb.createSheet("列表1");
for (int k = 0; k < list.size(); k++) {
SXSSFRow rows=sheet.createRow(k);
for (int j = 0; j <title.length; j++) {
SXSSFCell cell;
if(k==0){
//sheet.trackAllColumnsForAutoSizing();
cell=rows.createCell(j); //加载标题数据
cell.setCellValue(title[j]);
}else{
cell=rows.createCell(j); //加载数据
cell.setCellValue(list.get(k)[j]);
// System.out.printf("%S",list.get(k)[j]+" ");
}
// sheet.trackAllColumnsForAutoSizing();
// sheet.autoSizeColumn(j);
}
// System.out.println();
}
sheet.trackAllColumnsForAutoSizing();
wb.write(out);
out.close();
//wb.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
本文探讨了Java导出Excel的两种方法,包括使用较旧的jxl库和Apache POI。针对POI,文章详细说明了在处理大量数据时可能出现的内存泄漏问题,尤其是当数据超过256列或内存限制时。解决方案是利用SXSSFWorkbook类的构造函数,通过指定缓存行数来避免内存溢出。

1万+

被折叠的 条评论
为什么被折叠?



