定义一个帮助类,类的主要内容如下
private static Logger logger = Logger.getLogger(ExcelUtils.class);
private static final String DIRECTION_BOTTOM="bottom";
private static final String DIRECTION_RIGHT="right";
//判断单元格的模板"<开始-数据方向-截止>"
private static Map<String,String> isData(String value){
if(StringUtils.isNotBlank(value)){
Map<String,String> map=new HashMap<>();
String[] str=value.substring(1,value.length()-1).split("-");
map.put("start",str[0]);
map.put("direction",str[1]);
if(str.length==3){
map.put("end",str[2]);
}else{
map.put("end","n");
}
if(!(str[1].equals(DIRECTION_BOTTOM)||str[1].equals(DIRECTION_RIGHT))){
return null;
}
return map;
}
return null;
}
/**
* 格式化单元格
* @param cell
* @return
*/
public static String getStringValueFromCell(Cell cell) {
SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DecimalFormat decimalFormat = new DecimalFormat("#.##");
String cellValue = "";
if(cell == null) {
return cellValue;
}
else if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
cellValue = cell.getStringCellValue();
}
else if(cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
if(HSSFDateUtil.isCellDateFormatted(cell)) {
double d = cell.getNumericCellValue();
Date date = HSSFDateUtil.getJavaDate(d);
cellValue = sFormat.format(date);
}
else {
cellValue = decimalFormat.format((cell.getNumericCellValue()));
}
}
else if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {
cellValue = "";
}
else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
cellValue = String.valueOf(cell.getBooleanCellValue());
}
else if(cell.getCellType() == Cell.CELL_TYPE_ERROR) {
cellValue = "";
}
else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
cellValue = cell.getCellFormula().toString();
}
return cellValue;
}
private static Map<String,Integer> getMapMiddle(int x,int y,int index){
Map<String,Integer> map=new HashMap<>();
map.put("x",x);
map.put("y",y);
map.put("index",index);
return map;
}
/**
* 定位起始位置
* @param sheet
* @param index
* @param x
* @param y
* @param str
* @return
*/
private static Map<String,Integer> findIndexOfStartMiddle(XSSFSheet sheet, int index, int x, int y, String str) {
int count=1;
int i;
for(i=x;i<=sheet.getLastRowNum();i++){
XSSFRow dataRow=sheet.getRow(i);
if(dataRow==null)continue;
XSSFCell cell=dataRow.getCell(y);
if(cell==null)continue;
if(getStringValueFromCell(cell).equals(str)){
if(count==index){
return getMapMiddle(i,y,index);
}else if(count<index){
count++;
}else{
return null;
}
}
}
return null;
}
private static Map<String,Integer> findIndexOfEndMiddle(XSSFSheet sheet,String str,int index){
int count=0; //计数
for(int i=0;i<=sheet.getLastRowNum();i++){
XSSFRow dataRow=sheet.getRow(i);
if(dataRow==null)continue;
for(int j=0;j<=dataRow.getPhysicalNumberOfCells();j++){
XSSFCell cell=dataRow.getCell(j);
if(cell==null)continue;
if(getStringValueFromCell(cell).equals(str)){
if(++count==index){
return getMapMiddle(i,j,count);
}
}
}
}
return null;
}
/**
* 第一个参数是需要转换的数据,第二个参数是模板,第三个是是否为单据数据(不是为:1,是则填入单据的数据量)
* @param sheetData
* @param model
* @param count
* @return
*/
public static List<List<Map<String,List<Object>>>> getSheetDataMiddle(XSSFSheet sheetData,XSSFSheet model,int count) {
List<List<Map<String,List<Object>>>> allofList=new ArrayList<>();
for (int b =1;b<=count ;b++ ) { //循环单据的数量
List<Map<String,List<Object>>> allList=new ArrayList<>();
for (int mi = 0; mi <=model.getLastRowNum(); mi++) {
//模板的行
XSSFRow mRow = model.getRow(mi);
if (mRow == null) continue;
for(int mj=0;mj<=mRow.getPhysicalNumberOfCells();mj++) {
Cell modelCell = mRow.getCell(mj);
if (modelCell == null||getStringValueFromCell(modelCell).equals("<null>")) continue;
Map<String, String> cellData = isData(getStringValueFromCell(modelCell));
if (cellData == null) {
logger.error("模板的第" + (mi + 1) + "行,第" + (mj + 1) + "列单元格的数据类型不正确");
throw new BException("模板的第" + (mi + 1) + "行,第" + (mj + 1) + "列单元格的数据类型不正确");
} else {
Map<String, List<Object>> map=new HashMap<>();
int num=0; //单个单据的单属性的数据量
//获取该属性的起始坐标,
Map<String,Integer> start=findIndexOfStartMiddle(sheetData,b,mi,mj,cellData.get("start"));
Map<String,Integer> end=null;
if(!cellData.get("end").equals("n")){
end= findIndexOfEndMiddle(sheetData,cellData.get("end"),b);
}
if(start==null)continue;
//判断数据的方向
if(cellData.get("direction").equals(DIRECTION_BOTTOM)){
List<Object> list=new ArrayList<>();
if(end!=null){
//计算数量
num=Math.abs(start.get("x")-end.get("x"))-1;
if(num<=0)continue;
}
if(num!=0){
//数量确定,则到固定数量位置
for(int i=1;i<=num;i++){
list.add(getStringValueFromCell(sheetData.getRow(start.get("x")+i).getCell(start.get("y"))));
}
}else {
for (int i=1;;i++){
if(sheetData.getRow(start.get("x")+i)!=null){
XSSFCell cell=sheetData.getRow(start.get("x")+i).getCell(start.get("y"));
if(cell==null)break;
list.add(getStringValueFromCell(cell));
}else {
break;
}
}
}
map.put(cellData.get("start"),list);
}else if(cellData.get("direction").equals(DIRECTION_RIGHT)){
List<Object>list=new ArrayList<>();
if(end!=null){
num=Math.abs(start.get("y")-end.get("y"))-1;
if(num<=0)continue;
}
if(num!=0){
for(int j=1;j<=num;j++){
list.add(getStringValueFromCell(sheetData.getRow(start.get("x")).getCell(start.get("y")+j)));
}
}else{
for(int j=1;;j++){
XSSFCell cell=sheetData.getRow(start.get("x")).getCell(start.get("y")+j);
if(cell==null)break;
list.add(getStringValueFromCell(cell));
}
}
map.put(cellData.get("start"),list);
}
allList.add(map);
}
}
}
allofList.add(allList);
}
return allofList;
}
调用方法如下
File file1=new File("C:\\Users\\23228\\Desktop\\data.xlsx");
File file2=new File("C:\\Users\\23228\\Desktop\\model.xlsx");
InputStream inputStream1=new FileInputStream(file1);
XSSFWorkbook workbook1=new XSSFWorkbook(inputStream1);
XSSFSheet sheet1=workbook1.getSheetAt(1);
InputStream inputStream2=new FileInputStream(file2);
XSSFWorkbook workbook2=new XSSFWorkbook(inputStream2);
XSSFSheet sheet2=workbook2.getSheetAt(1);
List<List<Map<String,List<Object>>>> list=dd.getSheetDataMiddle(sheet1,sheet2,1);
模板1:<null>代表填充
数据如下:
数据如下:
模板2
数据:
数据:
主要用于处理报表的excel导出成数据,并按照一定的规律给后台处理,毕竟是初步完成的,如果还有其他想法的欢迎评论