近期做到关于java导入导出excel的功能,有感甩出下面代码。
package com.sf.sgs.ops.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
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.HSSFDateUtil;
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.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
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.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.sf.sgs.o2o.ops.dto.exam.ExamQuestionResp;
import com.sf.sgs.ops.utils.common.DateUtils;
import jxl.write.Alignment;
import jxl.write.Label;
import jxl.write.VerticalAlignment;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
public class ExcelReaderUtil {
// 默认单元格内容为数字时格式
private static DecimalFormat df = new DecimalFormat("0");
// 默认单元格格式化日期字符串
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static class ExcelRow {
// 所在行标,从1开始
private int row;
// 该行数据
private List<Object> datas = new ArrayList<>();
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
@Override
public String toString() {
return "ExcelRow [row=" + row + ", datas=" + datas + "]";
}
}
public static void testExport() {
String title = "课件题库数据";
String headersName[] = new String[] { "题目", "选项A", "选项B", "选项C", "选项D", "答案", "分值" };
String headersId[] = new String[] { "title", "option1", "option2", "option3", "option4", "answer", "score" };
List<ExamQuestionResp> list = new ArrayList<>();
ExamQuestionResp resp = new ExamQuestionResp();
resp.setTitle("aabbccdd");
resp.setOption1("11");
resp.setOption2("22");
resp.setOption3("33");
resp.setOption4("44");
resp.setAnswer("A");
short ss = 10;
resp.setScore(ss);
list.add(resp);
String filePath = "d://" + title + ".xlsx";
File file = new File(filePath);
// exportExcel(title, headersName, headersId, list, file, true);
}
/**
* 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出
*
* @param title
* 表格标题名
* @param headersName
* 表格属性列名数组
* @param headersId
* 表格属性列名对应的字段
* @param dataset
* 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象
* @param out
* 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
*/
public static <T> void exportExcel(String title, String[] headersName, String[] headersId, List<T> dtoList,
boolean isExcel2007, HttpServletResponse response) throws Exception {
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
response.setHeader("Content-disposition",
"attachment; filename=" + new String(title.getBytes("GB2312"), "ISO8859-1") + ".xlsx");// 设定输出文件头
response.setContentType("application/msexcel");// 定义输出类型
// 表头
Map<Integer, String> map = new HashMap<Integer, String>();
int key = 0;
for (int i = 0; i < headersName.length; i++) {
if (!headersName[i].equals(null)) {
map.put(key, headersName[i]);
key++;
}
}
// 字段
Map<Integer, String> zdMap = new HashMap<Integer, String>();
int value = 0;
for (int i = 0; i < headersId.length; i++) {
if (!headersId[i].equals(null)) {
zdMap.put(value, headersId[i]);
value++;
}
}
Workbook wb = null;
if (isExcel2007) {
wb = new XSSFWorkbook();
} else {
wb = new HSSFWorkbook();
}
// 声明一个工作薄
Sheet sheet = wb.createSheet(title);
sheet.setDefaultColumnWidth((short) 15);
// 生成一个样式
CellStyle style = wb.createCellStyle();
Row row = sheet.createRow(0);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
Cell cell;
Collection<String> c = map.values();
Iterator<String> it = c.iterator();
// 根据选择的字段生成表头
short size = 0;
while (it.hasNext()) {
cell = row.createCell(size);
cell.setCellValue(it.next().toString());
cell.setCellStyle(style);
size++;
}
// 字段
Collection<String> zdC = zdMap.values();
Iterator<T> labIt = dtoList.iterator();
int zdRow = 0;
while (labIt.hasNext()) {
int zdCell = 0;
zdRow++;
row = sheet.createRow(zdRow);
T l = (T) labIt.next();
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
Field[] fields = l.getClass().getDeclaredFields();
for (short i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
// System.out.println(fieldName);
Iterator<String> zdIt = zdC.iterator();
while (zdIt.hasNext()) {
if (zdIt.next().equals(fieldName)) {
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Class tCls = l.getClass();
try {
Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
Object val = getMethod.invoke(l, new Object[] {});
String textVal = null;
if (val != null) {
textVal = val.toString();
} else {
textVal = null;
}
row.createCell((short) zdCell).setCellValue(textVal);
zdCell++;
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
try {
wb.write(os);
wb.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出
*
* @param title
* 表格标题名
* @param headersName
* 表格属性列名数组
* @param headersId
* 表格属性列名对应的字段
* @param dataset
* 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象
* @param out
* 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
*/
public static <T> void exportNewExcel(String title, String[] headersName, String[] headersId, List<T> dtoList,
boolean isExcel2007, HttpServletResponse response) throws Exception {
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
response.setHeader("Content-disposition",
"attachment; filename=" + new String(title.getBytes("GB2312"), "ISO8859-1") + ".xlsx");// 设定输出文件头
response.setContentType("application/msexcel");// 定义输出类型
// 表头
Map<Integer, String> map = new HashMap<Integer, String>();
int key = 0;
for (int i = 0; i < headersName.length; i++) {
if (!headersName[i].equals(null)) {
map.put(key, headersName[i]);
key++;
}
}
// 字段
Map<Integer, String> zdMap = new HashMap<Integer, String>();
int value = 0;
for (int i = 0; i < headersId.length; i++) {
if (!headersId[i].equals(null)) {
zdMap.put(value, headersId[i]);
value++;
}
}
Workbook wb = null;
if (isExcel2007) {
wb = new XSSFWorkbook();
} else {
wb = new HSSFWorkbook();
}
// 声明一个工作薄
Sheet sheet = wb.createSheet(title);
sheet.setDefaultColumnWidth((short) 15);
// 生成一个样式
CellStyle style = wb.createCellStyle();
Row row = sheet.createRow(0);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
Cell cell;
Collection<String> c = map.values();
Iterator<String> it = c.iterator();
// 根据选择的字段生成表头
short size = 0;
while (it.hasNext()) {
cell = row.createCell(size);
cell.setCellValue(it.next().toString());
cell.setCellStyle(style);
size++;
}
// 字段
Collection<String> zdC = zdMap.values();
Iterator<T> labIt = dtoList.iterator();
int zdRow = 0;
while (labIt.hasNext()) {
int zdCell = 0;
zdRow++;
row = sheet.createRow(zdRow);
T l = (T) labIt.next();
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
Field[] fields = l.getClass().getDeclaredFields();
Iterator<String> zdIt = zdC.iterator();
while (zdIt.hasNext()) {
String tempName = zdIt.next();
for (short i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
if (fieldName.equals(tempName)) {
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Class tCls = l.getClass();
try {
Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
Object val = getMethod.invoke(l, new Object[] {});
String textVal = null;
String type = field.getGenericType().toString();
if (type.equals("class java.util.Date")) { // date类型
if (val != null) {
Date temp = (Date) val;
textVal = DateUtils.DateToStr(temp, DateUtils.FORMAT);
} else {
textVal = null;
}
} else {
if (val != null) {
textVal = val.toString();
} else {
textVal = null;
}
}
row.createCell((short) zdCell).setCellValue(textVal);
zdCell++;
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
try {
wb.write(os);
wb.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读取Excel文件,支持2007和2003两种版本 去掉空行,空单元格对应"",浮点数原样输出
*
* @param inputStream
* 输入流
* @param fileName
* 文件名称
* @param containTitle
* 是否包含表头
* @return
* @throws IOException
* List<List<Object>>
*/
@SuppressWarnings("deprecation")
public static List<ExcelRow> readExcel(InputStream inputStream, boolean isExcel2007, boolean containTitle)
throws IOException {
List<ExcelRow> rowList = new ArrayList<>();
try {
// 初始化Workbook对象
Workbook wb = null;
if (isExcel2007) {
wb = new XSSFWorkbook(inputStream);
} else {
wb = new HSSFWorkbook(inputStream);
}
// 读取标题行,获取列数
Sheet sheet = wb.getSheetAt(0);
// 第一列开始的行标
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
Row row = sheet.getRow(firstRowNum);
// 表头列数
int firstCellNum = row.getFirstCellNum();
int lastCellNum = row.getLastCellNum();
// 遍历数据表,i是游标,要将有数据的读完,中间没数据的行也加入
int i = firstRowNum;
if (!containTitle) {
i = firstRowNum + 1;
}
for (; i < lastRowNum + 1; i++) {
row = sheet.getRow(i);
// 一行数据
List<Object> colList = new ArrayList<Object>();
if (row == null) {
continue;
}
boolean allBlank = true;
for (int j = firstCellNum; j < lastCellNum; j++) {
Cell cell = row.getCell(j);
Object value = "";
if (cell == null) {
colList.add(value);
continue;
}
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING:
value = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
value = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle().getDataFormatString())) {
double num = cell.getNumericCellValue();
if (isInteger(num)) {
value = df.format(cell.getNumericCellValue());
} else {
value = num;
}
} else {
value = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()));
}
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
value = Boolean.valueOf(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_BLANK:
value = "";
break;
default:
value = cell.toString();
}// end switch
if (StringUtils.isNotBlank(value.toString())) {
allBlank = false;
}
colList.add(value);
} // end for j
if (!allBlank) {
ExcelRow excelRow = new ExcelRow();
excelRow.setRow(i + 1);
excelRow.setDatas(colList);
rowList.add(excelRow);
}
} // end for i
wb.close();
} catch (OfficeXmlFileException e) {
throw new IOException("文件后缀与实际文件类型不符", e);
}
return rowList;
}
// 判断整数(int)
private static boolean isInteger(double value) {
if (value % 1 == 0) {// 是这个整数,小数点后面是0
return true;
} else {// 不是整数,小数点后面不是0
return false;
}
}
public void testImport() {
String filePath = "e://demo.xlsx";
boolean isExcel2007 = false;
if (StringUtils.endsWithIgnoreCase(filePath, ".xlsx")) {
isExcel2007 = true;
}
FileInputStream inputStream;
try {
inputStream = new FileInputStream(new File(filePath));
List<ExcelRow> list = readExcel(inputStream, isExcel2007, true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeOneColumn() {
try
{
//打开文件
WritableWorkbook book= jxl.Workbook.createWorkbook(new File("d://tt.xls"));
//生成名为“第一页”的工作表,参数0表示这是第一页
WritableSheet sheet=book.createSheet("人员上班表",0);
//在Label对象的构造子中指名单元格位置是第一列第一行(0,0)
//以及单元格内容为test
WritableFont wfont3 = new WritableFont(WritableFont.ARIAL, 9,
WritableFont.NO_BOLD, false,
jxl.format.UnderlineStyle.NO_UNDERLINE,
jxl.format.Colour.AUTOMATIC);
WritableCellFormat titleFormat3 = new WritableCellFormat(wfont3);
titleFormat3.setWrap(true);//是否自动换行
sheet.setColumnView(0, 20);
Label label=new Label(0,0,"小白王(兼职)\r\n京东方",titleFormat3);
//将定义好的单元格添加到工作表中
sheet.addCell(label);
//第一列
for(int j=1;j<=24;j++) {
Label labelObj = null;
if(j< 11) {
labelObj=new Label(0,j, "0"+(j-1)+":00");
}else{
labelObj=new Label(0,j, (j-1)+":00");
}
sheet.addCell(labelObj);
}
//写入数据并关闭文件
book.write();
book.close();
}catch(Exception e)
{
System.out.println(e);
}
}
public static void main(String[] args) {
}
}
导出excel,尽量使用 【exportNewExcel】方法,谢谢。