1.工具类,读取单元格数据的时候,如果当前单元格是合并单元格,会自动读取合并单元格的值

 package com.shjh.core.util;
import java.io.IOException;
import java.io.InputStream; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelReaderUtil {
private static final String EXTENSION_XLS = "xls";
private static final String EXTENSION_XLSX = "xlsx";
private Workbook workbook = null;
private Sheet sheet = null;//表
private int sheetNum = 0; // 第sheetnum个工作表 public void setWorkbook(Workbook workbook) {
this.workbook = workbook;
} public void setSheet(Sheet sheet) {
this.sheet = sheet;
} public void setSheetNum(int sheetNum) {
this.sheetNum = sheetNum;
} public ExcelReaderUtil() {
} public ExcelReaderUtil(InputStream inputStream,String fileName) throws IOException {
if (fileName.endsWith(EXTENSION_XLS)) {
workbook = new HSSFWorkbook(inputStream);
} else if (fileName.endsWith(EXTENSION_XLSX)) {
workbook = new XSSFWorkbook(inputStream);
}
} /**
* 指定工作表、行、列下的内容
*
* @param sheetNum
* @param rowNum
* @param cellNum
* @return String
*/
public String getCellValue(int rowNum, int colNum) {
if (sheetNum < 0 || rowNum < 0){
return "";
}
String strExcelCell = "";
try {
sheet = this.workbook.getSheetAt(sheetNum);
//判断是否是合并单元格,如果是,就将行、列索引改为合并单元格的索引
for(int numMR = 0; numMR < this.sheet.getNumMergedRegions(); numMR++){
//获取合并单元格
CellRangeAddress cellRangeAddress = this.sheet.getMergedRegion(numMR);
int firstColumnInd = cellRangeAddress.getFirstColumn();
int lastColumnInd = cellRangeAddress.getLastColumn();
int firstRowInd = cellRangeAddress.getFirstRow();
int lastRowInd = cellRangeAddress.getLastRow();
//如果当前单元格在这个合并单元格里
if(rowNum >= firstRowInd && rowNum <= lastRowInd && colNum >= firstColumnInd && colNum <= lastColumnInd){
rowNum = firstRowInd;
colNum = firstColumnInd;
break;
}
}
Row row = sheet.getRow(rowNum);
if (row.getCell((short) colNum) != null) {
switch (row.getCell((short) colNum).getCellType()) {
case Cell.CELL_TYPE_FORMULA:
strExcelCell = "FORMULA ";
break;
case Cell.CELL_TYPE_NUMERIC: {
strExcelCell = String.valueOf(row.getCell((short) colNum).getNumericCellValue());
}
break;
case Cell.CELL_TYPE_STRING:
strExcelCell = row.getCell((short) colNum).getStringCellValue();
break;
case Cell.CELL_TYPE_BLANK:
strExcelCell = "";
break;
default:
strExcelCell = "";
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return strExcelCell;
} /**
* sheetNum下的记录行数
*
* @return int
*/
public int getRowCount() {
Sheet sheet = workbook.getSheetAt(this.sheetNum);
int rowCount = -1;
rowCount = sheet.getLastRowNum();
return rowCount;
}
}

2.Controller内调用,尤其要注意传参部分的写法,需要加上注解,且变量名必须和jsp页面里对应的参数名要完全一致。

     @RequestMapping(value="/excelUpload")
public void excelUpload(@RequestParam MultipartFile fileToUpload,@RequestParam String tableGroupId, HttpServletRequest request, HttpServletResponse response){
int nullLine=0;
String errorStr = "";
try {
ExcelReaderUtil readExcel = new ExcelReaderUtil(fileToUpload.getInputStream(),fileToUpload.getOriginalFilename());
readExcel.setSheetNum(0); // 设置读取索引为0的工作表
Map<String,String> checkRepeatMap=new HashMap<String,String>();//检验数据是否正常的集合
List<String> tabIdList=new ArrayList<String>();//最终得到的tableid集合
/*这里为循环校验数据*/
for (int i = 2; i < readExcel.getRowCount()+1; i++) {
String error="";
//库名,先判断是否在合并单元格内,若有则取合并单元格的值
String dataName=readExcel.getCellValue(i, 0).trim();//库
String moduleName1=readExcel.getCellValue(i, 1).trim();//一级模块
String moduleName2=readExcel.getCellValue(i, 2).trim();//二级模块
String moduleName3=readExcel.getCellValue(i, 3).trim();//三级模块
//String tableChiName=rows[4]==null ? "" :rows[4].trim();//表中文名 *暂时用不上
String tableEnName=readExcel.getCellValue(i, 5).trim().toUpperCase();//表物理名
//空行校验
if(StringUtils.isBlank(dataName) && StringUtils.isBlank(moduleName1) && StringUtils.isBlank(moduleName2) && StringUtils.isBlank(moduleName3) && StringUtils.isBlank(tableEnName))
{
nullLine++;
continue;
} //空校验
if(StringUtils.isBlank(tableEnName) )
{
error ="\n第"+(i+1)+"行:表物理名不能为空。\n";
errorStr+=error;
continue;
}
String mapValue=dataName+moduleName1+moduleName2+moduleName3+tableEnName;
if(checkRepeatMap.containsValue(mapValue)){
error ="\n第"+(i+1)+"行:该行数据为重复数据,请删除该行后重新提交。\n";
errorStr+=error;
continue;
}else{
checkRepeatMap.put((i+1)+"",mapValue);
}
/*各种校验*/
} if (StringUtils.isNotBlank(errorStr)) {
int errorCount=readExcel.getRowCount()-1-tabIdList.size()-nullLine;
OutPutUtil.ajaxOut(response, "导入失败!有"+errorCount+"条数据存在问题,请修正后再次导入:\n"+errorStr);
} else {
/*保存操作*/
}
} catch (Exception e) {
//logger.error("批量导入出错:"+e.getMessage().toString());
OutPutUtil.ajaxOut(response, "批量导入出错:"+e.getMessage().toString());
e.printStackTrace();
}
}

3.js代码,这里需要引用  ajaxfileupload.js 插件。参数名与controller里传入的参数名要一致。

         function ajaxFileUpload(){
if (checkFile()) { //此函数就不贴了,就是判断一下文件后缀名是否正确
//弹出遮盖层
$("#loadingDiv").show();
var tableGroupId = $("#tableGroupParam").val();
$.ajaxFileUpload({
url:'<%=basePath %>userController/excelUpload.do?tableGroupId='+tableGroupId,
secureuri:false,
fileElementId:'fileToUpload', //文件选择框的id属性
dataType: 'text',//服务器返回的格式,可以是json
//相当于java中try语句块的用法
success:function (data, status) {
//关闭遮盖层
$("#loadingDiv").hide();
alert(data);
},
error:function (data, status, e) {
alert("导入出错:"+data);
} }); }
}

4.html代码,就是用到了file控件,没什么特别的

         <div class="easyui-dialog" id="role-jurisdiction-dlg2" data-options="title:'批量导入',closed:true" style="width:400px;height:100px;">
<input type="hidden" id="tableGroupParam" value="0" class="input-xs" disabled="disabled">
<div id="loadingDiv">
<img src="<%=basePath %>/img/loading.gif" style="margin-top:5px;margin-left:120px;" />
</div>
<input type="file" name="fileToUpload" id="fileToUpload" size="300" style="width:300px" onchange="checkFile();">
<input type="button" name="btnUpload" value="上 传" id="btnUpload" style="width:60px" onclick="ajaxFileUpload();" />
</div>

Java Controller下兼容xls和xlsx且可识别合并单元格的excel导入功能的更多相关文章

  1. java导出标题多行且合并单元格的EXCEL

    场景:项目中遇到有需要导出Excel的需求,并且是多行标题且有合并单元格的,参考网上的文章,加上自己的理解,封装成了可自由扩展的导出工具 先上效果,再贴代码: 调用工具类进行导出: public st ...

  2. Java解析Excel工具类(兼容xls和xlsx)

    依赖jar <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml&l ...

  3. PHPEXCEL xls模板导入,及格式自定义:合并单元格、加粗、居中等操作

    PHPExcel 是用来操作Office Excel 文档的一个PHP类库,它基于微软的OpenXML标准和PHP语言.可以使用它来读取.写入不同格式的电子表格,如 Excel (BIFF) .xls ...

  4. java合并单元格同时导出excel

    POI进行跨行需要用到对象HSSFSheet对象,现在就当我们程序已经定义了一个HSSFSheet对象sheet. 跨第1行第1个到第2个单元格的操作为 sheet.addMergedRegion(n ...

  5. python3-xlwt-Excel设置(字体大小、颜色、对齐方式、换行、合并单元格、边框、背景、下划线、斜体、加粗)

    搬运出处: https://blog.csdn.net/weixin_44065501/article/details/88899257 # coding:utf-8 import patterns ...

  6. Java删除word合并单元格时的重复值

    Spire.Doc提供了Table.applyVerticalMerge()方法来垂直合并word文档里面的表格单元格,Table.applyHorizontalMerge()方法来水平合并表格单元格 ...

  7. java使用freemarker模板导出word(带有合并单元格)文档

    来自:https://blog.csdn.net/qq_33195578/article/details/73790283 前言:最近要做一个导出word功能,其实网上有很多的例子,但是我需要的是合并 ...

  8. java poi 合并单元格

    java poi 合并单元格 2017年03月29日 16:39:01 翠烟你懊恼 阅读数:26561   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.n ...

  9. Java导出Excel表,POI 实现合并单元格以及列自适应宽度(转载)

    POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...

随机推荐

  1. Maven_自动化构建和构建环节

    [构建过程的几个主要环节] ①清理:删除以前的编译结果,为重新编译做好准备. ②编译:将 Java 源程序编译为字节码文件. ③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性 ...

  2. CODEVS1222 信与信封问题 (匈牙利算法)

    先做一遍匈牙利算法.对于已经匹配的边,如果删去之后还能最大匹配数增加,则不符合要求. 一遍匈牙利算法是O(n^3)的,对于每一条边做n次,每次O(n^2),总的复杂度是O(n^3). 注意:不要忘记输 ...

  3. 四则运算结对编程(GUI)

    四则运算GUI coding地址:https://git.dev.tencent.com/qyj814/GUI.git 结对伙伴:李梦宇 一.题目要求 定制出题要求.每次出题时用户都可以在界面上定制如 ...

  4. HashMap源码分析3:移除

    本文源码基于JDK1.8.0_45. final Node<K,V> removeNode(int hash, Object key, Object value, boolean matc ...

  5. ZooKeeper实现配置中心的实例(原生API实现)(转)

    说明:要实现配置中心的例子,可以选择的SDK有很多,原生自带的SDK也是不错的选择.比如使用I0Itec,Spring Boot集成等. 大型应用通常会按业务拆分成一个个业务子系统,这些大大小小的子应 ...

  6. 【转】keyCode对照表及JS监听组合按键

    原文: http://blog.csdn.net/qq_21386275/article/details/67640576 有一些需求,html 页面上的input 框只允许输入数字,  只允许输入小 ...

  7. Django搭建简单的站点

    1.首先.新建一个项目(project), 名称为 mysite django-admin startproject mysite(假设 django-admin 不行,请用 django-admin ...

  8. IOS怎么实现一个UITableView的下拉刷新

    採用的EGORefreshTableHeaderView来实现: 在Controller上实现EGORefreshTableHeaderDelegate的delegate @property(nona ...

  9. (WIP) DPDK理论学习(by quqi99)

    作者:张华  发表于:2016-04-22版权声明:能够随意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 组成模 ...

  10. mysql 存储引擎的选择你会吗?

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXExMzU1NTQxNDQ4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...