爲什麼爲封裝此工具類?
由於公司供應鏈部門業務需要,對Excel處理這塊有較爲嚴苛的要求。爲了提高開發效率,從實際項目出發封裝了通用自定義讀取Excel工具類。
功能概述
- 支持讀取全部excel數據
- 支持自定義讀取(自定義讀取行、列)數據
- 支持讀取以title爲基準的數據(只讀取title下的行)
- 支持讀取圖片(返回圖片的位置和流)
- 支持設置sheet index讀取
- 支持讀取函數值
- 支持annation讀取列表值
/**
* 讀取excel文件內容
* 僅支持xlsx格式
* @author Vachel.Wang
* @date 2016年6月16日 下午5:10:18
* @version V1.2
*/
public class ReadExcel {
private XSSFWorkbook workbook = null;
private XSSFSheet sheet;
private XSSFRow row;
private int sheetIndex = 0 ;
private int rowIndex = 0 ;
private int cellIndex = 0 ;
public static ReadExcel me(InputStream s) throws IOException{
return new ReadExcel(s);
}
public ReadExcel(InputStream s) throws IOException{
workbook = new XSSFWorkbook(s);
setSheetIndex(0);
}
public <T> List<T> readCoustomTemplet(Class<T> clazz) throws InstantiationException, IllegalAccessException {
List<T> list = new ArrayList<T>();
XSSFRow titleRow = sheet.getRow(rowIndex-1);
ArrayList<String> rowArr = new ArrayList<String>();
int cells = titleRow.getPhysicalNumberOfCells();
for (int j = cellIndex; j < cells; j++) {
rowArr.add(getStringCellValue(titleRow.getCell(j)));
}
List<Field> allFields = getMappedFiled(clazz, null);
Map<String, Field> fieldsMap = new HashMap<String, Field>();//定義一個map用於存放列的序號和field.
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelField.class)) {
ExcelField attr = field.getAnnotation(ExcelField.class);
field.setAccessible(true);
fieldsMap.put(attr.title(), field);
}
}
//row = sheet.getRow(rowIndex);
for (int i = rowIndex ; i < sheet.getPhysicalNumberOfRows(); i++) {
row = sheet.getRow(i);
T entity = null;
for (int j = cellIndex; j < cells; j++) {
String c = getStringCellValue(row.getCell(j));
entity = (entity == null ? clazz.newInstance() : entity);// 如果不存在實例則新建.
Field field = fieldsMap.get(rowArr.get(j));// 從map中得到對應列的field.
if (field==null) {
continue;
}
Class<?> fieldType = field.getType();
if (String.class == fieldType) {
field.set(entity, String.valueOf(c));
} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
field.set(entity, Integer.parseInt(c));
} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
field.set(entity, Long.valueOf(c));
} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
field.set(entity, Float.valueOf(c));
} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
field.set(entity, Short.valueOf(c));
} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
field.set(entity, Double.valueOf(c));
} else if (Character.TYPE == fieldType) {
if ((c != null) && (c.length() > 0)) {
field.set(entity, Character.valueOf(c.charAt(0)));
}
}
}
if (entity != null) {
list.add(entity);
}
}
return list;
}
private List<Field> getMappedFiled(Class clazz, List<Field> fields) {
if (fields == null) {
fields = new ArrayList<Field>();
}
Field[] allFields = clazz.getDeclaredFields();// 得到所有定義字段
// 得到所有field並存放到一個list中.
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelField.class)) {
fields.add(field);
}
}
if (clazz.getSuperclass() != null && !clazz.getSuperclass().equals(Object.class)) {
getMappedFiled(clazz.getSuperclass(), fields);
}
return fields;
}
/**
* 讀取自定義讀取方式數據
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readCoustom() throws FileNotFoundException, IOException{
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = rowIndex ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
for (int j = cellIndex; j < row.getPhysicalNumberOfCells(); j++) {
rowArr.add(getStringCellValue(row.getCell(j)));
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 以title列爲標準讀取自定義數據
* @param titleIndex
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readCoustomByTitle(int titleIndex) throws FileNotFoundException, IOException{
XSSFRow titleRow = sheet.getRow(titleIndex);
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = rowIndex ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
for (int j = cellIndex; j < titleRow.getPhysicalNumberOfCells(); j++) {
rowArr.add(getStringCellValue(row.getCell(j)));
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 讀取自定義讀取非空數據
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readCoustomExcludeNull() throws FileNotFoundException, IOException{
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = rowIndex ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
for (int j = cellIndex; j < row.getPhysicalNumberOfCells(); j++) {
String cellValue = getStringCellValue(row.getCell(j));
if(!cellValue.equals(""))
rowArr.add(cellValue);
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 讀取所有
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readAll() throws FileNotFoundException, IOException{
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = 0 ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
rowArr.add(getStringCellValue(row.getCell(j)));
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 以title行爲標準來讀其它所有取列值
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readAllByTitle(int titleIndex) throws FileNotFoundException, IOException{
XSSFRow titleRow = sheet.getRow(titleIndex);
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = 0 ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
if(row==null)
continue;
for (int j = 0; j < titleRow.getPhysicalNumberOfCells(); j++) {
rowArr.add(getStringCellValue(row.getCell(j)));
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 讀取title行下的所有數據
* @param titleIndex
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readNextByTitle(int titleIndex) throws FileNotFoundException, IOException{
XSSFRow titleRow = sheet.getRow(titleIndex);
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = titleIndex+1 ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
if(row==null){
continue;
}
for (int j = 0; j < titleRow.getPhysicalNumberOfCells(); j++) {
rowArr.add(getStringCellValue(row.getCell(j)));
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 讀取非空數據
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public List<ArrayList<String>> readAllExcludeNull() throws FileNotFoundException, IOException{
List<ArrayList<String>> excelData = new ArrayList<ArrayList<String>>();
for (int i = 0 ; i < sheet.getPhysicalNumberOfRows(); i++) {
ArrayList<String> rowArr = new ArrayList<String>();
row = sheet.getRow(i);
for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
String cellValue = getStringCellValue(row.getCell(j));
if(!cellValue.equals(""))
rowArr.add(cellValue);
}
excelData.add(rowArr);
}
return excelData;
}
/**
* 讀取行的所有列的數據
* @param rowIndex
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public ArrayList<String> readRowData(int rowIndex) throws FileNotFoundException, IOException{
ArrayList<String> rowDataArr = new ArrayList<String>();
row = sheet.getRow(rowIndex);
for (int i = 0 ; i < row.getPhysicalNumberOfCells(); i++) {
String cellStr = getStringCellValue(row.getCell(i));
rowDataArr.add(cellStr);
}
return rowDataArr;
}
/**
* 讀取行的所有列的非空數據
* @param rowIndex
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public ArrayList<String> readRowExcludeNullData(int rowIndex) throws FileNotFoundException, IOException{
ArrayList<String> rowDataArr = new ArrayList<String>();
row = sheet.getRow(rowIndex);
for (int i = 0 ; i < row.getPhysicalNumberOfCells(); i++) {
String cellValue = getStringCellValue(row.getCell(i));
if(!cellValue.equals(""))
rowDataArr.add(cellValue);
}
return rowDataArr;
}
/**
* 讀取讀列的數據
* 空爲 ""
* @param rowIndex
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public String readCellData(int rowIndex , int cellIndex) throws FileNotFoundException, IOException{
row = sheet.getRow(rowIndex);
return getStringCellValue(row.getCell(cellIndex));
}
/**
* 獲取所有圖片
* @return
*/
public List<XSSFPictureData> readPictures() {
return workbook.getAllPictures();
}
/**
* 讀取單元格內容,支持獲取函數內容
* @param cell
* @return
*/
public static String getStringCellValue(Cell cell) {
String strCell = "";
if(cell==null) return strCell;
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING: // get String data
strCell = cell.getRichStringCellValue().getString().trim();
break;
case Cell.CELL_TYPE_NUMERIC: // get date or number data
if (DateUtil.isCellDateFormatted(cell)) {
strCell = com.gjw.utils.DateUtil.formatYYYYMMDDHHMMSS(cell.getDateCellValue());
} else {
BigDecimal numberic=new BigDecimal(cell.getNumericCellValue());
strCell = numberic.toPlainString();
}
break;
case Cell.CELL_TYPE_BOOLEAN: // get boolean data
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: // get expression data
FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
evaluator.evaluateFormulaCell(cell);
CellValue cellValue = evaluator.evaluate(cell);
if(StringUtil.isNotBlank(cellValue.getStringValue())){
strCell = String.valueOf(cellValue.getStringValue()) ;
}else{
strCell = String.valueOf(cellValue.getNumberValue()) ;
}
break;
default:
strCell = "";
}
return strCell;
}
/**
* 設置讀取sheet下標,默認爲0
* @param sheetIndex
* @return
*/
public ReadExcel setSheetIndex(int sheetIndex){
this.sheetIndex = sheetIndex ;
sheet = workbook.getSheetAt(sheetIndex);
return this;
}
/**
* 設置讀取sheet下標,默認爲0
* @param rowIndex
* @return
*/
public ReadExcel setRowIndex(int rowIndex){
this.rowIndex = rowIndex ;
return this;
}
/**
* 設置讀取cell下標,默認爲0
* @param rowIndex
* @return
*/
public ReadExcel setCellIndex(int cellIndex){
this.cellIndex = cellIndex ;
return this;
}
/**
* 獲取sheet總數
* @return
*/
public int getSheetCount(){
return this.workbook.getNumberOfSheets();
}
/**
* 根據sheet下標獲取sheet名稱
* @param index
* @return
*/
public String getSheetNameByIndex(int index){
return this.workbook.getSheetAt(index).getSheetName();
}
public String getCurrentSheetName(){
return this.workbook.getSheetAt(sheetIndex).getSheetName();
}
/**
* 獲取Excel2007圖片
* @param sheetNum 當前sheet編號
* @param sheet 當前sheet對象
* @param workbook 工作簿對象
* @return Map key:圖片單元格索引(0_1_1)String,value:圖片流PictureData
*/
public static Map<String, PictureData> getSheetPictrues(int sheetNum,
XSSFSheet sheet, XSSFWorkbook workbook) {
Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
for (POIXMLDocumentPart dr : sheet.getRelations()) {
if (dr instanceof XSSFDrawing) {
XSSFDrawing drawing = (XSSFDrawing) dr;
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
XSSFPicture pic = (XSSFPicture) shape;
XSSFClientAnchor anchor = pic.getPreferredSize();
CTMarker ctMarker = anchor.getFrom();
String picIndex = String.valueOf(sheetNum) + "_"
+ ctMarker.getRow() + "_" + ctMarker.getCol();
sheetIndexPicMap.put(picIndex, pic.getPictureData());
}
}
}
return sheetIndexPicMap;
}
public static void printImg(List<Map<String, XSSFPictureData>> sheetList) throws IOException {
for (Map<String, XSSFPictureData> map : sheetList) {
Object key[] = map.keySet().toArray();
for (int i = 0; i < map.size(); i++) {
// 獲取圖片流
XSSFPictureData pic = map.get(key[i]);
// 獲取圖片索引
String picName = key[i].toString();
// 獲取圖片格式
String ext = pic.suggestFileExtension();
byte[] data = pic.getData();
FileOutputStream out = new FileOutputStream("D:\\pic" + picName + "." + ext);
out.write(data);
out.close();
}
}
}
public XSSFWorkbook getWorkbook() {
return workbook;
}
public XSSFSheet getSheet() {
return sheet;
}
public int getSheetIndex() {
return sheetIndex;
}
public static void main(String[] args) throws IOException {
/*InputStream inputStream = new FileInputStream("d:\\success3.xlsx");
try {
List<ScmInvoiceImportLog> list = ReadExcel.me(inputStream).setSheetIndex(0).setRowIndex(1).readCoustomTemplet(ScmInvoiceImportLog.class);
System.out.println(list);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
// list all demo
/*List<ArrayList<String>> list = ReadExcel.me(inputStream).setSheetIndex(0).readAllByTitle(4);
for(ArrayList<String> rowArray : list){
for(String string : rowArray){
System.out.print(string+"\t");
}
System.out.println();
}*/
// read picture demo
/*List<XSSFPictureData> readPictures = ReadExcel.me(inputStream).readPictures();
for(XSSFPictureData pictureData:readPictures){
int type = pictureData.getPictureType();
if(type == Workbook.PICTURE_TYPE_JPEG){
File file = new File("d:\\"+System.currentTimeMillis()+".jpg");
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(pictureData.getData());
outputStream.flush();
outputStream.close();
}
}*/
/*ReadExcel readExcel = ReadExcel.me(inputStream).setSheetIndex(0);
Map<String, PictureData> dataMap = readExcel.getSheetPictrues(readExcel.getSheetIndex(),readExcel.getSheet(),readExcel.getWorkbook());
for(Map.Entry<String,PictureData> entry : dataMap.entrySet()){
System.out.println("key = "+entry.getKey()+" , value = "+entry.getValue());
}*/
}
}
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {
/**
* 導出字段名(默認調用當前字段的“get”方法,如指定導出字段爲對象,請填寫“對象名.對象屬性”,例:“area.name”、“office.name”)
*/
String value() default "";
/**
* 導出字段標題(需要添加批註請用“**”分隔,標題**批註,僅對導出模板有效)
*/
String title();
/**
* 字段類型(0:導出導入;1:僅導出;2:僅導入)
*/
int type() default 0;
/**
* 導出字段對齊方式(0:自動;1:靠左;2:居中;3:靠右)
*/
int align() default 0;
/**
* 導出字段字段排序(升序)
*/
int sort() default 0;
/**
* 如果是字典類型,請設置字典的type值
*/
String dictType() default "";
/**
* 反射類型
*/
Class<?> fieldType() default Class.class;
/**
* 字段歸屬組(根據分組導出導入)
*/
int[] groups() default {};
}