Java导出Excel通用工具类实例代码

网友投稿 286 2022-10-29


Java导出Excel通用工具类实例代码

一、概述

相信大家在工作过程中,都会遇到这样一个需求,就是将相关的数据列表导出成excel,那么,有没有通用的导出方式呢,这里,就带着大家一起来用java实现一个通用的导出Excel的工具。

二、项目实现

1、构建pom.xml

我们的工程是利用Maven来构建的,项目具体搭建过程大家可以参见网上其他资料,这里我们仅给出最核心的Maven配置

org.apache.poi

poi-scratchpad

3.11-beta2

org.apache.poi

poi-ooxml

3.11-beta2

org.apache.poi

poi-ooxml-schemas

3.11-beta2

org.apache.poi

poi-excelant</artifactId>

3.11-beta2

2、编写ExportExcelUtil类

这个类使我们整个工具的核心,它实现了Excel文件的导出功能,具体代码如下:

package com.lyz.utils.excel.poi;

import java.io.IOException;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.text.SimpleDateFormat;

import java.util.Collection;

import java.util.Date;

import java.util.Iterator;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import org.apache.poi.hssf.usermodel.HSSFFont;

import org.apache.poi.hssf.usermodel.HSSFRichTextString;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.util.HSSFColor;

import org.apache.poi.xssf.usermodel.XSSFCell;

import org.apache.poi.xssf.usermodel.XSSFCellStyle;

import org.apache.poi.xssf.usermodel.XSSFColor;

import org.apache.poi.xssf.usermodel.XSSFFont;

import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import org.apache.poi.xssf.usermodel.XSSFRow;

import org.apache.poi.xssf.usermodel.XSSFSheet;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**

* 导出Excel

* @author liuyazhuang

*

* @param

*/

public class ExportExcelUtil{

// 2007 版本以上 最大支持1048576行

public final static String EXCEl_FILE_2007 = "2007";

// 2003 版本 最大支持65536 行

public final static String EXCEL_FILE_2003 = "2003";

/**

*

* 导出无头部标题行Excel

* 时间格式默认:yyyy-MM-dd hh:mm:ss

*

*

* @param title 表格标题

* @param dataset 数据集合

* @param out 输出流

* @param version 2003 或者 2007,不传时默认生成2003版本

*/

public void exportExcel(String title, Collection dataset, OutputStream out, String version) {

if(StringUtils.isEmpty(version) || EXCEL_FILE_2003.equals(version.trim())){

exportExcel2003(title, null, dataset, out, "yyyy-MM-dd HH:mm:ss");

}else{

exportExcel2007(title, null, dataset, out, "yyyy-MM-dd HH:mm:ss");

}

}

/**

*

* 导出带有头部标题行的Excel

* 时间格式默认:yyyy-MM-dd hh:mm:ss

*

*

* @param title 表格标题

* @param headers 头部标题集合

* @param dataset 数据集合

* @param out 输出流

* @param version 2003 或者 2007,不传时默认生成2003版本

*/

public void exportExcel(String title,String[] headers, Collection dataset, OutputStream out,String version) {

if(StringUtils.isBlank(version) || EXCEL_FILE_2003.equals(version.trim())){

exportExcel2003(title, headers, dataset, out, "yyyy-MM-dd HH:mm:ss");

}else{

exportExcel2007(title, headers, dataset, out, "yyyy-MM-dd HH:mm:ss");

}

}

/**

*

* 通用Excel导出方法,利用反射机制遍历对象的所有字段,将数据写入Excel文件中

* 此版本生成2007以上版本的文件 (文件后缀:xlsx)

*

*

* @param title

* 表格标题名

* @param headers

* 表格头部标题集合

* @param dataset

* 需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。此方法支持的

* JavaBean属性的数据类型有基本数据类型及String,Date

* @param out

* 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中

* @param pattern

* 如果有时间数据,设定输出格式。默认为"yyyy-MM-dd hh:mm:ss"

*/

@SuppressWarnings({ "unchecked", "rawtypes" })

public void exportExcel2007(String title, String[] headers, Collection dataset, OutputStream out, String pattern) {

// 声明一个工作薄

XSSFWorkbook workbook = new XSSFWorkbook();

// 生成一个表格

XSSFSheet sheet = workbook.createSheet(title);

// 设置表格默认列宽度为15个字节

sheet.setDefaultColumnWidth(20);

// 生成一个样式

XSSFCellStyle style = workbook.createCellStyle();

// 设置这些样式

style.setFillForegroundColor(new XSSFColor(java.awt.Color.gray));

style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);

style.setBorderBottom(XSSFCellStyle.BORDER_THIN);

style.setBorderLeft(XSSFCellStyle.BORDER_THIN);

style.setBorderRight(XSSFCellStyle.BORDER_THIN);

style.setBorderTop(XSSFCellStyle.BORDER_THIN);

style.setAlignment(XSSFCellStyle.ALIGN_CENTER);

// 生成一个字体

XSSFFont font = workbook.createFont();

font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);

font.setFontName("宋体");

font.setColor(new XSSFColor(java.awt.Color.BLACK));

font.setFontHeightInPoints((short) 11);

// 把字体应用到当前的样式

style.setFont(font);

// 生成并设置另一个样式

XSSFCellStyle style2 = workbook.createCellStyle();

style2.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));

style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);

style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);

style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);

style2.setBorderRight(XSSFCellStyle.BORDER_THIN);

style2.setBorderTop(XSSFCellStyle.BORDER_THIN);

style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);

style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);

// 生成另一个字体

XSSFFont font2 = workbook.createFont();

font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);

// 把字体应用到当前的样式

style2.setFont(font2);

// 产生表格标题行

XSSFRow row = sheet.createRow(0);

XSSFCell cellHeader;

for (int i = 0; i < headers.length; i++) {

cellHeader = row.createCell(i);

cellHeader.setCellStyle(style);

cellHeader.setCellValue(new XSSFRichTextString(headers[i]));

}

// 遍历集合数据,产生数据行

Iterator it = dataset.iterator();

int index = 0;

T t;

Field[] fields;

Field field;

XSSFRichTextString richString;

Pattern p = Pattern.compile("^//d+(//.//d+)?$");

Matcher matcher;

String fieldName;

String getMethodName;

XSSFCell cell;

Class tCls;

Method getMethod;

Object value;

String textValue;

SimpleDateFormat sdf = new SimpleDateFormat(pattern);

while (it.hasNext()) {

index++;

row = sheet.createRow(index);

t = (T) it.next();

// 利用反射,根据JavaBean属性的先后顺序,动态调用getXxx()方法得到属性值

fields = t.getClass().getDeclaredFields();

for (int i = 0; i < fields.length; i++) {

cell = row.createCell(i);

cell.setCellStyle(style2);

field = fields[i];

fieldName = field.getName();

getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()

+ fieldName.substring(1);

try {

tCls = t.getClass();

getMethod = tCls.getMethod(getMethodName, new Class[] {});

value = getMethod.invoke(t, new Object[] {});

// 判断值的类型后进行强制类型转换

textValue = null;

if (value instanceof Integer) {

cell.setCellValue((Integer) value);

} else if (value instanceof Float) {

textValue = String.valueOf((Float) value);

cell.setCellValue(textValue);

} else if (value instanceof Double) {

textValue = String.valueOf((Double) value);

cell.setCellValue(textValue);

} else if (value instanceof Long) {

cell.setCellValue((Long) value);

}

if (value instanceof Boolean) {

textValue = "是";

if (!(Boolean) value) {

textValue = "否";

}

} else if (value instanceof Date) {

textValue = sdf.format((Date) value);

} else {

// 其它数据类型都当作字符串简单处理

if (value != null) {

textValue = value.toString();

}

}

if (textValue != null) {

matcher = p.matcher(textValue);

if (matcher.matches()) {

// 是数字当作double处理

cell.setCellValue(Double.parseDouble(textValue));

} else {

richString = new XSSFRichTextString(textValue);

cell.setCellValue(richString);

}

}

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} finally {

// 清理资源

}

}

}

try {

workbook.write(out);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

*

* 通用Excel导出方法,利用反射机制遍历对象的所有字段,将数据写入Excel文件中

* 此方法生成2003版本的excel,文件名后缀:xls

*

*

* @param title

* 表格标题名

* @param headers

* 表格头部标题集合

* @param dataset

* 需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。此方法支持的

* JavaBean属性的数据类型有基本数据类型及String,Date

* @param out

* 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中

* @param pattern

* 如果有时间数据,设定输出格式。默认为"yyyy-MM-dd hh:mm:ss"

*/

@SuppressWarnings({ "unchecked", "rawtypes" })

public void exportExcel2003(String title, String[] headers, Collection dataset, OutputStream out, String pattern) {

// 声明一个工作薄

HSSFWorkbook workbook = new HSSFWorkbook();

// 生成一个表格

HSSFSheet sheet = workbook.createSheet(title);

// 设置表格默认列宽度为15个字节

sheet.setDefaultColumnWidth(20);

// 生成一个样式

HSSFCellStyle style = workbook.createCellStyle();

// 设置这些样式

style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index);

style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

style.setBorderBottom(HSSFCellStyle.BORDER_THIN);

style.setBorderLeft(HSSFCellStyle.BORDER_THIN);

style.setBorderRight(HSSFCellStyle.BORDER_THIN);

style.setBorderTop(HSSFCellStyle.BORDER_THIN);

style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

// 生成一个字体

HSSFFont font = workbook.createFont();

font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

font.setFontName("宋体");

font.setColor(HSSFColor.WHITE.index);

font.setFontHeightInPoints((short) 11);

// 把字体应用到当前的样式

style.setFont(font);

// 生成并设置另一个样式

HSSFCellStyle style2 = workbook.createCellStyle();

style2.setFillForegroundColor(HSSFColor.WHITE.index);

style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);

style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);

style2.setBorderRight(HSSFCellStyle.BORDER_THIN);

style2.setBorderTop(HSSFCellStyle.BORDER_THIN);

style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);

style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

// 生成另一个字体

HSSFFont font2 = workbook.createFont();

font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);

// 把字体应用到当前的样式

style2.setFont(font2);

// 产生表格标题行

HSSFRow row = sheet.createRow(0);

HSSFCell cellHeader;

for (int i = 0; i < headers.length; i++) {

cellHeader = row.createCell(i);

cellHeader.setCellStyle(style);

cellHeader.setCellValue(new HSSFRichTextString(headers[i]));

}

http://

// 遍历集合数据,产生数据行

Iterator it = dataset.iterator();

int index = 0;

T t;

Field[] fields;

Field field;

HSSFRichTextString richString;

Pattern p = Pattern.compile("^//d+(//.//d+)?$");

Matcher matcher;

String fieldName;

String getMethodName;

HSSFCell cell;

Class tCls;

Method getMethod;

Object value;

String textValue;

SimpleDateFormat sdf = new SimpleDateFormat(pattern);

while (it.hasNext()) {

index++;

row = sheet.createRow(index);

t = (T) it.next();

// 利用反射,根据JavaBean属性的先后顺序,动态调用getXxx()方法得到属性值

fields = t.getClass().getDeclaredFields();

for (int i = 0; i < fields.length; i++) {

cell = row.createCell(i);

cell.setCellStyle(style2);

field = fields[i];

fieldName = field.getName();

getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()

+ fieldName.substring(1);

try {

tCls = t.getClass();

getMethod = tCls.getMethod(getMethodName, new Class[] {});

value = getMethod.invoke(t, new Object[] {});

// 判断值的类型后进行强制类型转换

textValue = null;

if (value instanceof Integer) {

cell.setCellValue((Integer) value);

} else if (value instanceof Float) {

textValue = String.valueOf((Float) value);

cell.setCellValue(textValue);

} else if (value instanceof Double) {

textValue = String.valueOf((Double) value);

cell.setCellValue(textValue);

} else if (value instanceof Long) {

cell.setCellValue((Long) value);

}

if (value instanceof Boolean) {

textValue = "是";

if (!(Boolean) value) {

textValue = "否";

}

} else if (value instanceof Date) {

textValue = sdf.format((Date) value);

} else {

// 其它数据类型都当作字符串简单处理

if (value != null) {

textValue = value.toString();

}

}

if (textValue != null) {

matcher = p.matcher(textValue);

if (matcher.matches()) {

// 是数字当作double处理

cell.setCellValue(Double.parseDouble(textValue));

} else {

richString = new HSSFRichTextString(textValue);

cell.setCellValue(richString);

}

}

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} finally {

// 清理资源

}

}

}

try {

workbook.write(out);

} catch (IOException e) {

e.printStackTrace();

}

}

}

为了演示导出功能,这里我们创建了一个Student学生类。

3、创建Student类

package com.lyz.utils.excel.poi;

/**

* 例子JavaBean

* @author liuyazhuang

*

*/

public class Student {

private int id;

private String name;

private String sex;

public Student(int id, String name, String sex) {

this.id = id;

this.name = name;

this.sex = sex;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

}

4、创建测试类TestExportExcelUtil

这个类,主要是用来测试我们的工具类。具体代码如下:

package com.lyz.test;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.List;

import com.lyz.utils.excel.poi.ExportExcelUtil;

import com.lyz.utils.excel.poi.Student;

/**

* 测试文件导出

* @author liuyazhuang

*

*/

public class TestExportExcelUtil {

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

ExportExcelUtil util = new ExportExcelUtil();

// 准备数据

List list = new ArrayList<>();

for (int i = 0; i < 10; i++) {

list.add(new Student(111,"张三asdf","男"));

list.add(new Student(111,"李四asd","男"));

list.add(new Student(111,"王五","女"));

}

String[] columnNames = { "ID", "姓名", "性别" };

util.exportExcel("用户导出", columnNames, list, new FileOutputStream("E:/test.xls"), ExportExcelUtil.EXCEL_FILE_2003);

}

}

5、测试

我们运行TestExportExcelUtil类,会发现在我们的E盘下生成了test.xls文件,具体如下:

三、项目扩展

以上实现均是在本地磁盘生成excel文件,但更多的时候,我们需要通过点击网页上的某个按钮来自动生成并下载Excel文档,那么,这又如何实现呢?下面我们就一起来实现这个功能。

1、扩展ExportExcelUtil类

根据Java的继承思想,我们不在ExportExcelUtil类上修改添加,我们创建一个ExportExcelUtil类的子类ExportExcelWrapper,这个类继承ExportExcelUtil的所有功能,同时,扩展了网页生成Excel的功能。具体代码如下:

package com.lyz.utils.excel.poi;

import java.net.URLEncoder;

import java.util.Collection;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

/**

* 包装类

* @author liuyazhuang

*

* @param

*/

public class ExportExcelWrapper extends ExportExcelUtil {

/**

*

* 导出带有头部标题行的Excel

* 时间格式默认:yyyy-MM-dd hh:mm:ss

*

*

* @param title 表格标题

* @param headers 头部标题集合

* @param dataset 数据集合

* @param out 输出流

* @param version 2003 或者 2007,不传时默认生成2003版本

*/

public void exportExcel(String fileName, String title, String[] headers, Collection dataset, HttpServletResponse response,String version) {

try {

response.setContentType("application/vnd.ms-excel");

response.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8") + ".xls");

if(StringUtils.isBlank(version) || EXCEL_FILE_2003.equals(version.trim())){

exportExcel2003(title, headers, dataset, response.getOutputStream(), "yyyy-MM-dd HH:mm:ss");

}else{

exportExcel2007(title, headers, dataset, response.getOutputStream(), "yyyy-MM-dd HH:mm:ss");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

这样,我们可以在Controller层调用ExportExcelWrapper将相关的数据和HttpServletResponse传递进来,即可实现通过网页生生并下载Excel文档了。

2、编写Controller类

@Controller("test")

@RequestMapping("/test")

public class TestController {

@RequestMapping("/get/excel")

public void getExcel(HttpServletRequest request, HttpServletResponse response) throws Exception {

// 准备数据

List list = new ArrayList<>();

for (int i = 0; i < 10; i++) {

list.add(new Student(111,"张三asdf","男"));

list.add(new Student(111,"李四asd","男"));

list.add(new Student(111,"王五","女"));

}

String[] columnNames = { "ID", "姓名", " 性别"};

String fileName = "excel1";

ExportExcelWrapper util = new ExportExcelWrapper();

util.exportExcel(fileName, fileName, columnNames, list, response, ExportExcelUtil.EXCEL_FILE_2003);

}

}

3、编写index.html

这个网页很简单,具体实现如下:

4、测试

我们将程序发布到Tomcat,并点击网上的按钮,效果如下:

我们打开excel1.xls文件如下:

至此,我们的工具就编写完成了。

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:网络基础学习笔记
下一篇:华为交换机命令行操作小结
相关文章

 发表评论

暂时没有评论,来抢沙发吧~