近期做到关于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】方法,谢谢。