package com.xx.utils; import java.io.FileInputStream; import java.io.IOException; import java.text.DecimalFormat; import java.util.Date; import java.util.HashMap; import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @SuppressWarnings({"rawtypes","unchecked"}) public class ExcelUtil { /** * 取得指定单元格行和列 * @param keyMap 所有单元格行、列集合 * @param key 单元格标识 * @return 0:列 1:行(列表型数据不记行,即1无值) */ public static int[] getPos(HashMap keyMap, String key){ int[] ret = new int[0]; String val = (String)keyMap.get(key); if(val == null || val.length() == 0) return ret; String pos[] = val.split(","); if(pos.length == 1 || pos.length == 2){ ret = new int[pos.length]; for(int i0 = 0; i0 < pos.length; i0++){ if(pos[i0] != null && pos[i0].trim().length() > 0){ ret[i0] = Integer.parseInt(pos[i0].trim()); } else { ret[i0] = 0; } } } return ret; } /** * 取对应格子的值 * @param sheet * @param rowNo 行 * @param cellNo 列 * @return * @throws IOException */ public static String getCellValue(Sheet sheet,int rowNo,int cellNo) { String cellValue = null; Row row = sheet.getRow(rowNo); Cell cell = row.getCell(cellNo); if (cell != null) { if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { DecimalFormat df = new DecimalFormat("0"); cellValue = getCutDotStr(df.format(cell.getNumericCellValue())); } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) { cellValue = cell.getStringCellValue(); } if (cellValue != null) { cellValue = cellValue.trim(); } } else { cellValue = null; } return cellValue; } /** * 取整数 * @param srcString * @return */ private static String getCutDotStr(String srcString) { String newString = ""; if (srcString != null && srcString.endsWith(".0")) { newString = srcString.substring(0,srcString.length()-2); } else { newString = srcString; } return newString; } /** * 读数据模板 * @param 模板地址 * @throws IOException */ public static HashMap[] getTemplateFile(String templateFileName) throws IOException { FileInputStream fis = new FileInputStream(templateFileName); Workbook wbPartModule = null; if(templateFileName.endsWith(".xlsx")){ wbPartModule = new XSSFWorkbook(fis); }else if(templateFileName.endsWith(".xls")){ wbPartModule = new HSSFWorkbook(fis); } int numOfSheet = wbPartModule.getNumberOfSheets(); HashMap[] templateMap = new HashMap[numOfSheet]; for(int i = 0; i < numOfSheet; i++){ Sheet sheet = wbPartModule.getSheetAt(i); templateMap[i] = new HashMap(); readSheet(templateMap[i], sheet); } fis.close(); return templateMap; } /** * 读模板数据的样式值置等信息 * @param keyMap * @param sheet */ private static void readSheet(HashMap keyMap, Sheet sheet){ int firstRowNum = sheet.getFirstRowNum(); int lastRowNum = sheet.getLastRowNum(); for (int j = firstRowNum; j <= lastRowNum; j++) { Row rowIn = sheet.getRow(j); if(rowIn == null) { continue; } int firstCellNum = rowIn.getFirstCellNum(); int lastCellNum = rowIn.getLastCellNum(); for (int k = firstCellNum; k <= lastCellNum; k++) { // Cell cellIn = rowIn.getCell((short) k); Cell cellIn = rowIn.getCell(k); if(cellIn == null) { continue; } int cellType = cellIn.getCellType(); if(Cell.CELL_TYPE_STRING != cellType) { continue; } String cellValue = cellIn.getStringCellValue(); if(cellValue == null) { continue; } cellValue = cellValue.trim(); if(cellValue.length() > 2 && cellValue.substring(0,2).equals("<%")) { String key = cellValue.substring(2, cellValue.length()); String keyPos = Integer.toString(k)+","+Integer.toString(j); keyMap.put(key, keyPos); keyMap.put(key+"CellStyle", cellIn.getCellStyle()); } else if(cellValue.length() > 3 && cellValue.substring(0,3).equals("<!%")) { String key = cellValue.substring(3, cellValue.length()); keyMap.put("STARTCELL", Integer.toString(j)); keyMap.put(key, Integer.toString(k)); keyMap.put(key+"CellStyle", cellIn.getCellStyle()); } } } } /** * 获取格式,不适于循环方法中使用,wb.createCellStyle()次数超过4000将抛异常 * @param keyMap * @param key * @return */ public static CellStyle getStyle(HashMap keyMap, String key,Workbook wb) { CellStyle cellStyle = null; cellStyle = (CellStyle) keyMap.get(key+"CellStyle"); //当字符超出时换行 cellStyle.setWrapText(true); CellStyle newStyle = wb.createCellStyle(); newStyle.cloneStyleFrom(cellStyle); return newStyle; } /** * Excel单元格输出 * @param sheet * @param row 行 * @param cell 列 * @param value 值 * @param cellStyle 样式 */ public static void setValue(Sheet sheet, int row, int cell, Object value, CellStyle cellStyle){ Row rowIn = sheet.getRow(row); if(rowIn == null) { rowIn = sheet.createRow(row); } Cell cellIn = rowIn.getCell(cell); if(cellIn == null) { cellIn = rowIn.createCell(cell); } if(cellStyle != null) { //修复产生多超过4000 cellStyle 异常 //CellStyle newStyle = wb.createCellStyle(); //newStyle.cloneStyleFrom(cellStyle); cellIn.setCellStyle(cellStyle); } //对时间格式进行单独处理 if(value==null){ cellIn.setCellValue(""); }else{ if (isCellDateFormatted(cellStyle)) { cellIn.setCellValue((Date) value); } else { cellIn.setCellValue(new XSSFRichTextString(value.toString())); } } } /** * 根据表格样式判断是否为日期格式 * @param cellStyle * @return */ public static boolean isCellDateFormatted(CellStyle cellStyle){ if(cellStyle==null){ return false; } int i = cellStyle.getDataFormat(); String f = cellStyle.getDataFormatString(); return org.apache.poi.ss.usermodel.DateUtil.isADateFormat(i, f); } /** * 适用于导出的数据Excel格式样式重复性较少 * 不适用于循环方法中使用 * @param wbModule * @param sheet * @param pos 模板文件信息 * @param startCell 开始的行 * @param value 要填充的数据 * @param cellStyle 表格样式 */ public static void createCell(Workbook wbModule, Sheet sheet,HashMap pos, int startCell,Object value,String cellStyle){ int[] excelPos = getPos(pos, cellStyle); setValue(sheet, startCell, excelPos[0], value, getStyle(pos, cellStyle,wbModule)); } }
package com.XX.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * 对excel进行操作工具类 *@author xiliang.xiao *@date 2015年1月8日 下午1:46:36 * **/ @SuppressWarnings("rawtypes") public class ExcelHandle { private Map<String,HashMap[]> tempFileMap = new HashMap<String,HashMap[]>(); private Map<String,Map<String,Cell>> cellMap = new HashMap<String,Map<String,Cell>>(); private Map<String,FileInputStream> tempStream = new HashMap<String, FileInputStream>(); private Map<String,Workbook> tempWorkbook = new HashMap<String, Workbook>(); private Map<String,Workbook> dataWorkbook = new HashMap<String, Workbook>(); /** * 单无格类 * @author xiliang.xiao * */ class Cell{ private int column;//列 private int line;//行 private CellStyle cellStyle; public int getColumn() { return column; } public void setColumn(int column) { this.column = column; } public int getLine() { return line; } public void setLine(int line) { this.line = line; } public CellStyle getCellStyle() { return cellStyle; } public void setCellStyle(CellStyle cellStyle) { this.cellStyle = cellStyle; } } /** * 向Excel中输入相同title的多条数据 * @param tempFilePath excel模板文件路径 * @param cellList 需要填充的数据(模板<!%后的字符串) * @param dataList 填充的数据 * @param sheet 填充的excel sheet,从0开始 * @throws IOException */ public void writeListData(String tempFilePath,List<String> cellList,List<Map<String,Object>> dataList,int sheet) throws IOException{ //获取模板填充格式位置等数据 HashMap temp = getTemp(tempFilePath,sheet); //按模板为写入板 Workbook temWorkbook = getTempWorkbook(tempFilePath); //获取数据填充开始行 int startCell = Integer.parseInt((String)temp.get("STARTCELL")); //数据填充的sheet Sheet wsheet = temWorkbook.getSheetAt(sheet); //移除模板开始行数据即<!% wsheet.removeRow(wsheet.getRow(startCell)); if(dataList!=null&&dataList.size()>0){ for(Map<String,Object> map:dataList){ for(String cell:cellList){ //获取对应单元格数据 Cell c = getCell(cell,temp,temWorkbook,tempFilePath); //写入数据 ExcelUtil.setValue(wsheet, startCell, c.getColumn(), map.get(cell), c.getCellStyle()); } startCell++; } } } /** * 按模板向Excel中相应地方填充数据 * @param tempFilePath excel模板文件路径 * @param cellList 需要填充的数据(模板<%后的字符串) * @param dataMap 填充的数据 * @param sheet 填充的excel sheet,从0开始 * @throws IOException */ public void writeData(String tempFilePath,List<String> cellList,Map<String,Object> dataMap,int sheet) throws IOException{ //获取模板填充格式位置等数据 HashMap tem = getTemp(tempFilePath,sheet); //按模板为写入板 Workbook wbModule = getTempWorkbook(tempFilePath); //数据填充的sheet Sheet wsheet = wbModule.getSheetAt(sheet); if(dataMap!=null&&dataMap.size()>0){ for(String cell:cellList){ //获取对应单元格数据 Cell c = getCell(cell,tem,wbModule,tempFilePath); ExcelUtil.setValue(wsheet, c.getLine(), c.getColumn(), dataMap.get(cell), c.getCellStyle()); } } } /** * Excel文件读值 * @param tempFilePath * @param cell * @param sheet * @return * @throws IOException */ public Object getValue(String tempFilePath,String cell,int sheet,File excelFile) throws IOException{ //获取模板填充格式位置等数据 HashMap tem = getTemp(tempFilePath,sheet); //模板工作区 Workbook temWorkbook = getTempWorkbook(tempFilePath); //数据工作区 Workbook dataWorkbook = getDataWorkbook(tempFilePath, excelFile); //获取对应单元格数据 Cell c = getCell(cell,tem,temWorkbook,tempFilePath); //数据sheet Sheet dataSheet = dataWorkbook.getSheetAt(sheet); return ExcelUtil.getCellValue(dataSheet, c.getLine(), c.getColumn()); } /** * 读值列表值 * @param tempFilePath * @param cell * @param sheet * @return * @throws IOException */ public List<Map<String,Object>> getListValue(String tempFilePath,List<String> cellList,int sheet,File excelFile) throws IOException{ List<Map<String,Object>> dataList = new ArrayList<Map<String,Object>>(); //获取模板填充格式位置等数据 HashMap tem = getTemp(tempFilePath,sheet); //获取数据填充开始行 int startCell = Integer.parseInt((String)tem.get("STARTCELL")); //将Excel文件转换为工作区间 Workbook dataWorkbook = getDataWorkbook(tempFilePath,excelFile) ; //数据sheet Sheet dataSheet = dataWorkbook.getSheetAt(sheet); //文件最后一行 int lastLine = dataSheet.getLastRowNum(); for(int i=startCell;i<=lastLine;i++){ dataList.add(getListLineValue(i, tempFilePath, cellList, sheet, excelFile)); } return dataList; } /** * 读值一行列表值 * @param tempFilePath * @param cell * @param sheet * @return * @throws IOException */ public Map<String,Object> getListLineValue(int line,String tempFilePath,List<String> cellList,int sheet,File excelFile) throws IOException{ Map<String,Object> lineMap = new HashMap<String, Object>(); //获取模板填充格式位置等数据 HashMap tem = getTemp(tempFilePath,sheet); //按模板为写入板 Workbook temWorkbook = getTempWorkbook(tempFilePath); //将Excel文件转换为工作区间 Workbook dataWorkbook = getDataWorkbook(tempFilePath,excelFile) ; //数据sheet Sheet dataSheet = dataWorkbook.getSheetAt(sheet); for(String cell:cellList){ //获取对应单元格数据 Cell c = getCell(cell,tem,temWorkbook,tempFilePath); lineMap.put(cell, ExcelUtil.getCellValue(dataSheet, line, c.getColumn())); } return lineMap; } /** * 获得模板输入流 * @param tempFilePath * @return * @throws FileNotFoundException */ private FileInputStream getFileInputStream(String tempFilePath) throws FileNotFoundException { if(!tempStream.containsKey(tempFilePath)){ tempStream.put(tempFilePath, new FileInputStream(tempFilePath)); } return tempStream.get(tempFilePath); } /** * 获得输入工作区 * @param tempFilePath * @return * @throws IOException * @throws FileNotFoundException */ private Workbook getTempWorkbook(String tempFilePath) throws FileNotFoundException, IOException { if(!tempWorkbook.containsKey(tempFilePath)){ if(tempFilePath.endsWith(".xlsx")){ tempWorkbook.put(tempFilePath, new XSSFWorkbook(getFileInputStream(tempFilePath))); }else if(tempFilePath.endsWith(".xls")){ tempWorkbook.put(tempFilePath, new HSSFWorkbook(getFileInputStream(tempFilePath))); } } return tempWorkbook.get(tempFilePath); } /** * 获取对应单元格样式等数据数据 * @param cell * @param tem * @param wbModule * @param tempFilePath * @return */ private Cell getCell(String cell, HashMap tem, Workbook wbModule, String tempFilePath) { if(!cellMap.get(tempFilePath).containsKey(cell)){ Cell c = new Cell(); int[] pos = ExcelUtil.getPos(tem, cell); if(pos.length>1){ c.setLine(pos[1]); } c.setColumn(pos[0]); c.setCellStyle((ExcelUtil.getStyle(tem, cell, wbModule))); cellMap.get(tempFilePath).put(cell, c); } return cellMap.get(tempFilePath).get(cell); } /** * 获取模板数据 * @param tempFilePath 模板文件路径 * @param sheet * @return * @throws IOException */ private HashMap getTemp(String tempFilePath, int sheet) throws IOException { if(!tempFileMap.containsKey(tempFilePath)){ tempFileMap.put(tempFilePath, ExcelUtil.getTemplateFile(tempFilePath)); cellMap.put(tempFilePath, new HashMap<String,Cell>()); } return tempFileMap.get(tempFilePath)[sheet]; } /** * 资源关闭 * @param tempFilePath 模板文件路径 * @param os 输出流 * @throws IOException * @throws FileNotFoundException */ public void writeAndClose(String tempFilePath,OutputStream os) throws FileNotFoundException, IOException{ if(getTempWorkbook(tempFilePath)!=null){ getTempWorkbook(tempFilePath).write(os); tempWorkbook.remove(tempFilePath); } if(getFileInputStream(tempFilePath)!=null){ getFileInputStream(tempFilePath).close(); tempStream.remove(tempFilePath); } } /** * 获得读取数据工作间 * @param tempFilePath * @param excelFile * @return * @throws IOException * @throws FileNotFoundException */ private Workbook getDataWorkbook(String tempFilePath, File excelFile) throws FileNotFoundException, IOException { if(!dataWorkbook.containsKey(tempFilePath)){ if(tempFilePath.endsWith(".xlsx")){ dataWorkbook.put(tempFilePath, new XSSFWorkbook(new FileInputStream(excelFile))); }else if(tempFilePath.endsWith(".xls")){ dataWorkbook.put(tempFilePath, new HSSFWorkbook(new FileInputStream(excelFile))); } } return dataWorkbook.get(tempFilePath); } /** * 读取数据后关闭 * @param tempFilePath */ public void readClose(String tempFilePath){ dataWorkbook.remove(tempFilePath); } public static void main(String args[]) throws IOException{ String tempFilePath = ExcelHandle.class.getResource("test.xlsx").getPath(); List<String> dataListCell = new ArrayList<String>(); dataListCell.add("names"); dataListCell.add("ages"); dataListCell.add("sexs"); dataListCell.add("deses"); List<Map<String,Object>> dataList = new ArrayList<Map<String,Object>>(); Map<String,Object> map = new HashMap<String, Object>(); map.put("names", "names"); map.put("ages", 22); map.put("sexs", "男"); map.put("deses", "测试"); dataList.add(map); Map<String,Object> map1 = new HashMap<String, Object>(); map1.put("names", "names1"); map1.put("ages", 23); map1.put("sexs", "男"); map1.put("deses", "测试1"); dataList.add(map1); Map<String,Object> map2 = new HashMap<String, Object>(); map2.put("names", "names2"); map2.put("ages", 24); map2.put("sexs", "女"); map2.put("deses", "测试2"); dataList.add(map2); Map<String,Object> map3 = new HashMap<String, Object>(); map3.put("names", "names3"); map3.put("ages", 25); map3.put("sexs", "男"); map3.put("deses", "测试3"); dataList.add(map3); ExcelHandle handle = new ExcelHandle(); handle.writeListData(tempFilePath, dataListCell, dataList, 0); List<String> dataCell = new ArrayList<String>(); dataCell.add("name"); dataCell.add("age"); dataCell.add("sex"); dataCell.add("des"); Map<String,Object> dataMap = new HashMap<String, Object>(); dataMap.put("name", "name"); dataMap.put("age", 11); dataMap.put("sex", "女"); dataMap.put("des", "测试"); handle.writeData(tempFilePath, dataCell, dataMap, 0); File file = new File("d:/data.xlsx"); OutputStream os = new FileOutputStream(file); //写到输出流并关闭资源 handle.writeAndClose(tempFilePath, os); os.flush(); os.close(); System.out.println("读取写入的数据----------------------------------%%%"); System.out.println("name:"+handle.getValue(tempFilePath, "name", 0, file)); System.out.println("age:"+handle.getValue(tempFilePath, "age", 0, file)); System.out.println("sex:"+handle.getValue(tempFilePath, "sex", 0, file)); System.out.println("des:"+handle.getValue(tempFilePath, "des", 0, file)); System.out.println("读取写入的列表数据----------------------------------%%%"); List<Map<String,Object>> list = handle.getListValue(tempFilePath, dataListCell, 0, file); for(Map<String,Object> data:list){ for(String key:data.keySet()){ System.out.print(key+":"+data.get(key)+"--"); } System.out.println(""); } handle.readClose(tempFilePath); } }
读取写入的数据----------------------------------%%%
name:name
age:11
sex:女
des:测试
读取写入的列表数据----------------------------------%%%
names:names--deses:测试--sexs:男--ages:22--
names:names1--deses:测试1--sexs:男--ages:23--
names:names2--deses:测试2--sexs:女--ages:24--
names:names3--deses:测试3--sexs:男--ages:25--