POI操作Excel導入和導出
Apache的POI組件是Java操作Microsoft Office辦公套件的強大API,其中對Word,Excel和PowperPoint都有支持,當然使用較多的還是Excel,因為Word和PowerPoint用程序動態操作的應用較少。那么本文就結合POI來介紹一下操作Excel的方法。
這里介紹兩種方法實現excel的操作。代碼都有注釋,可以很清楚的看懂,一種是循環遍歷excel表格,這個要自己定位一個excel的起點。另外一種是通過java反射機制實現的,根據表頭來實現映射。具體代碼如下:
第一種:
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFCell; 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.POIFSFileSystem; 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.util.Region; public class ExcelUtils { /** * 讀取EXCEL * @param firstrow 從第幾行開始讀取 * @return 讀取后返回數組 */ @SuppressWarnings("deprecation") public static String[][] importExcel(File file, int firstrow) throws FileNotFoundException, IOException { List<String[]> result = new ArrayList<String[]>(); int rowSize = 0; BufferedInputStream in = new BufferedInputStream(new FileInputStream( file)); POIFSFileSystem fs = new POIFSFileSystem(in); HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFCell cell = null; for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) { HSSFSheet st = wb.getSheetAt(sheetIndex); for (int rowIndex = firstrow; rowIndex <= st.getLastRowNum(); rowIndex++) { HSSFRow row = st.getRow(rowIndex); if (row == null) { continue; } int tempRowSize = row.getLastCellNum() + 1; if (tempRowSize > rowSize) { rowSize = tempRowSize; } String[] values = new String[rowSize]; Arrays.fill(values, ""); boolean hasValue = false; for (short columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) { String value = ""; cell = row.getCell(columnIndex); if (cell != null) { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_STRING://讀取的格式為字符串 value = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_NUMERIC://讀取的格式為數組 //如果格式為日期格式,自定義格式輸出 if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); if (date != null) { value = new SimpleDateFormat("yyyy-MM-dd") .format(date); } else { value = ""; } } else { //如果格式為數值,自定義格式輸出 value = new DecimalFormat().format(cell .getNumericCellValue()); } break; case HSSFCell.CELL_TYPE_FORMULA: // 導入時如果為公式生成的數據則無值 value = ""; break; // 導入時如果為空 case HSSFCell.CELL_TYPE_BLANK: break; case HSSFCell.CELL_TYPE_ERROR: value = ""; break; // 導入時如果為BOOLEAN型 自定義格式輸出 case HSSFCell.CELL_TYPE_BOOLEAN: value = (cell.getBooleanCellValue() == true ? "Y" : "N"); break; default: value = ""; } } values[columnIndex] = rightTrim(value); hasValue = true; } if (hasValue) { result.add(values); } } in.close(); String[][] returnArray = new String[result.size()][rowSize]; for (int i = 0; i < returnArray.length; i++) { returnArray[i] = (String[]) result.get(i); } return returnArray; } return null; } /** * 去掉字符串右邊的空格 * * @param str 要處理的字符串 * @return 處理后的字符串 */ public static String rightTrim(String str) { if (str == null) { return ""; } int length = str.length(); for (int i = length - 1; i >= 0; i--) { if (str.charAt(i) != 0x20) { break; } length--; } return str.substring(0, length); } /** * 創建通用EXCEL頭部 * * @param headString 頭部顯示的字符 * @param colSum 該報表的列數 */ @SuppressWarnings("deprecation") public void createNormalHead(String headString, int colSum,HSSFSheet sheet,HSSFWorkbook wb) { HSSFRow row1 = sheet.createRow(0); // 設置第一行 HSSFCell cell = row1.createCell(0); row1.setHeight((short) 800); // 定義單元格為字符串類型 cell.setCellType(HSSFCell.ENCODING_UTF_16); cell.setCellValue(new HSSFRichTextString(headString)); // 指定合并區域 sheet.addMergedRegion(new Region(0, (short) 0, 0, (short) colSum)); HSSFCellStyle cellStyle = wb.createCellStyle(); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定單元格居中對齊 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定單元格垂直居中對齊 //cellStyle.setWrapText(true);// 指定單元格自動換行 // 設置單元格字體 HSSFFont font = wb.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋體"); font.setFontHeight((short) 300); cellStyle.setFont(font); cell.setCellStyle(cellStyle); } /** * 創建通用報表第二行的格式 * */ public HSSFCellStyle getCellStyle(HSSFWorkbook wb) { // 創建單元格樣式 HSSFCellStyle cellStyle = wb.createCellStyle(); // 指定單元格居中對齊 cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定單元格垂直居中對齊 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 指定當單元格內容顯示不下時自動換行 //cellStyle.setWrapText(true); // 設置單元格字體 HSSFFont font = wb.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); font.setFontName("宋體"); font.setFontHeight((short) 200); //font.setFontHeightInPoints((short) 22); cellStyle.setFont(font); return cellStyle; } }
第二種:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; 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.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.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; public class ExcelUtil<T> { /** * 從excel導入,返回一個list集合 * * @author * @param file * 導入的excel文件 * @param pattern * @return * */ Class<T> clazz; public ExcelUtil(Class<T> clazz) { this.clazz = clazz; } @SuppressWarnings("unchecked") public Collection<T> importExcel(File file, String... pattern) throws Exception { Collection<T> dist = new ArrayList<T>(); try { /** * 類反射得到調用方法 */ // 得到目標目標類的所有的字段列表 Field filed[] = clazz.getDeclaredFields(); // 將所有標有Annotation的字段,也就是允許導入數據的字段,放入到一個map中 Map fieldmap = new HashMap(); // 循環讀取所有字段 for (int i = 0; i < filed.length; i++) { Field f = filed[i]; // 得到單個字段上的Annotation ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class); // 如果標識了Annotationd的話 if (exa != null) { // 構造設置了Annotation的字段的Setter方法 String fieldname = f.getName(); String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); // 構造調用的method, Method setMethod = clazz.getMethod(setMethodName, new Class[] { f.getType() }); // 將這個method以Annotaion的名字為key來存入。 fieldmap.put(exa.exportName(), setMethod); } } /** * excel的解析開始 */ // 將傳入的File構造為FileInputStream; FileInputStream in = new FileInputStream(file); // // 得到工作表 HSSFWorkbook book = new HSSFWorkbook(in); // // 得到第一頁 HSSFSheet sheet = book.getSheetAt(0); // // 得到第一面的所有行 Iterator<Row> row = sheet.rowIterator(); /** * 標題解析 */ // 得到第一行,也就是標題行 Row title = row.next(); // 得到第一行的所有列 Iterator<Cell> cellTitle = title.cellIterator(); // 將標題的文字內容放入到一個map中。 Map titlemap = new HashMap(); // 從標題第一列開始 int i = 0; // 循環標題所有的列 while (cellTitle.hasNext()) { Cell cell = cellTitle.next(); String value = cell.getStringCellValue(); // 還是把表頭trim一下 value = value.trim(); titlemap.put(i, value); i = i + 1; } /** * 解析內容行 */ // 用來格式化日期的DateFormat SimpleDateFormat sf; if (pattern.length < 1) { sf = new SimpleDateFormat("yyyy-MM-dd"); } else sf = new SimpleDateFormat(pattern[0]); while (row.hasNext()) { // 標題下的第一行 Row rown = row.next(); // 行的所有列 Iterator<Cell> cellbody = rown.cellIterator(); // 得到傳入類的實例 T tObject = clazz.newInstance(); int k = 0; // 遍歷一行的列 while (cellbody.hasNext()) { Cell cell = cellbody.next(); // 這里得到此列的對應的標題 String titleString = (String) titlemap.get(k); // 如果這一列的標題和類中的某一列的Annotation相同,那么則調用此類的的set方法,進行設值 if (fieldmap.containsKey(titleString)) { Method setMethod = (Method) fieldmap.get(titleString); // 得到setter方法的參數 Type[] ts = setMethod.getGenericParameterTypes(); // 只要一個參數 String xclass = ts[0].toString(); // 判斷參數類型 try { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC: // 數字 if (xclass.equals("class java.lang.String")) { if ((cell.getNumericCellValue() + "") .indexOf(".") > 0) { setMethod .invoke(tObject, (cell.getNumericCellValue() + "") .substring( 0, (cell.getNumericCellValue() + "") .lastIndexOf("."))); } } else if (xclass .equals("class java.lang.Integer")) { setMethod.invoke(tObject, (int) cell.getNumericCellValue()); } else if (xclass.equals("int")) { setMethod.invoke(tObject, (int) cell.getNumericCellValue()); } break; case HSSFCell.CELL_TYPE_STRING: // 字符串 if (xclass.equals("class java.lang.Integer")) { setMethod.invoke(tObject, Integer.parseInt(cell .getStringCellValue())); } else if (xclass .equals("class java.lang.String")) { setMethod.invoke(tObject, cell .getStringCellValue().trim()); } else if (xclass.equals("int")) { int temp = Integer.parseInt(cell .getStringCellValue()); setMethod.invoke(tObject, temp); } break; case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean Boolean boolname = true; if (cell.getStringCellValue().equals("否")) { boolname = false; } setMethod.invoke(tObject, boolname); break; case HSSFCell.CELL_TYPE_FORMULA: // 公式 System.out.print(cell.getCellFormula() + " "); break; case HSSFCell.CELL_TYPE_BLANK: // 空值 System.out.println(" "); break; case HSSFCell.CELL_TYPE_ERROR: // 故障 System.out.println(" "); break; default: System.out.print("未知類型 "); break; } } catch (Exception e) {// 轉換出錯 e.printStackTrace(); } } // 下一列 k = k + 1; } dist.add(tObject); } } catch (Exception e) { e.printStackTrace(); // 將異常拋出去 throw e; } return dist; } // 格式化日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); /** * 導出到excel中去, * * @author Administrator * @param title * excel的工作表名 * @param fileName * excel 文件名 * @param dateset * 導出的數據集合 * @param out * 輸出流 * @throws IOException */ @SuppressWarnings({ "static-access" }) public void exportExcel(String title, String fileName, List<T> dataset, String totalMoney, HttpServletResponse response) throws IOException { OutputStream out = response.getOutputStream();// 取得輸出流 response.reset();// 清空輸出流 response.setContentType("application/ms-excel;charset=GB2312"); response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("gb2312"), "iso8859-1") + ".xls"); // 聲明一個工作薄 try { HSSFWorkbook workbook = new HSSFWorkbook(); // 首先檢查數據看是否是正確的 if (dataset == null || dataset.size() == 0 || title == null || out == null) { throw new Exception("傳入的數據不對!"); } // 取得實際泛型類 T ts = (T) dataset.get(0); Class<?> tCls = ts.getClass(); // 生成一個表格 HSSFSheet sheet = workbook.createSheet(title); // 設置表格默認列寬度為15個字節 sheet.setDefaultColumnWidth(15); // 生成一個樣式 HSSFCellStyle style = workbook.createCellStyle(); // 設置標題樣式 style = this.setHeadStyle(workbook, style); // 得到所有字段 Field filed[] = ts.getClass().getDeclaredFields(); // 標題 List<String> exportfieldtile = new ArrayList<String>(); // 導出的字段的get方法 List<Method> methodObj = new ArrayList<Method>(); // 遍歷整個filed for (int i = 0; i < filed.length; i++) { Field f = filed[i]; ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class); // 如果設置了annottion if (exa != null) { String exprot = exa.exportName(); // 添加到標題 exportfieldtile.add(exprot); // 添加到需要導出的字段的方法 String fieldname = f.getName(); String getMethodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); Method getMethod = tCls.getMethod(getMethodName, new Class[] {}); methodObj.add(getMethod); } } sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, exportfieldtile .size() - 1)); HSSFRow titleRow = sheet.createRow(0); HSSFCell titleCell = titleRow.createCell(0); titleCell.setCellValue(title); titleCell.setCellStyle(this.setTitleStyle(workbook, workbook.createCellStyle())); // 產生表格標題行 HSSFRow row = sheet.createRow(1); for (int i = 0; i < exportfieldtile.size(); i++) { HSSFCell cell = row.createCell(i); cell.setCellStyle(style); HSSFRichTextString text = new HSSFRichTextString( exportfieldtile.get(i)); cell.setCellValue(text); } int index = 1; // 循環整個list for (int j = 0; j < dataset.size(); j++) { // 從第二行開始寫,第一行是標題 T t = (T) dataset.get(j); row = sheet.createRow(index + 1); for (int k = 0; k < methodObj.size(); k++) { HSSFCell cell = row.createCell(k); Method getMethod = methodObj.get(k); Object value = getMethod.invoke(t, new Object[] {}); String textValue = getValue(value); cell.setCellValue(textValue); } index++; } //總的項目筆數 HSSFRow totalNumRow = sheet.createRow(index + 2); HSSFCell totalNumCellTitle = totalNumRow.createCell(0); totalNumCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle())); totalNumCellTitle.setCellValue("項目筆數"); HSSFCell totalNumCell = totalNumRow.createCell(1); totalNumCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle())); totalNumCell.setCellValue(dataset.size()); //總金額 HSSFRow totalMoneyRow = sheet.createRow(index + 3); HSSFCell totalMoneyCellTitle = totalMoneyRow.createCell(0); totalMoneyCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle())); totalMoneyCellTitle.setCellValue("總金額"); HSSFCell totalMoneyCell = totalMoneyRow.createCell(1); totalMoneyCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle())); totalMoneyCell.setCellValue(totalMoney + "萬元"); workbook.write(out); } catch (Exception e) { e.printStackTrace(); } } public String getValue(Object value) { String textValue = ""; if (value == null) return textValue; if (value instanceof Boolean) { boolean bValue = (Boolean) value; textValue = "是"; if (!bValue) { textValue = "否"; } } else if (value instanceof Date) { Date date = (Date) value; textValue = sdf.format(date); } else textValue = value.toString(); return textValue; } /** * 初始化導出的excel標題的樣式 * */ public static HSSFCellStyle setTitleStyle(HSSFWorkbook workbook, HSSFCellStyle style) { style.setFillForegroundColor(HSSFColor.WHITE.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.setColor(HSSFColor.BLACK.index); font.setFontHeightInPoints((short) 16); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 把字體應用到當前的樣樣式 style.setFont(font); return style; } /** * 統計部分的樣式 * @param workbook * @param style * @return */ public static HSSFCellStyle setStatStyle(HSSFWorkbook workbook, HSSFCellStyle style) { style.setFillForegroundColor(HSSFColor.WHITE.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_NONE); style.setBorderLeft(HSSFCellStyle.BORDER_NONE); style.setBorderRight(HSSFCellStyle.BORDER_NONE); style.setBorderTop(HSSFCellStyle.BORDER_NONE); style.setAlignment(HSSFCellStyle.ALIGN_LEFT); // 生成字體 HSSFFont font = workbook.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 把字體應用到當前的樣樣式 style.setFont(font); return style; } /** * 初始化導出的excel樣式 * */ public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook, HSSFCellStyle style) { style.setFillForegroundColor(HSSFColor.SKY_BLUE.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.setColor(HSSFColor.VIOLET.index); font.setFontHeightInPoints((short) 12); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 把字體應用到當前的樣樣式 style.setFont(font); return style; } public static HSSFCellStyle setbodyStyle(HSSFWorkbook workbook, HSSFCellStyle style2) { style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.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); return style2; } }
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 用于Excel導出時給每個pojo對象的字段添加字段名稱,作為excel的表頭 * * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ExcelAnnotation { // excel導出時標題顯示的名字,如果沒有設置Annotation屬性,將不會被導出和導入 public String exportName(); }
來自: http://blog.csdn.net//u011067360/article/details/24416541
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!