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. lombok 插件安装

    1. 下载地址: https://plugins.jetbrains.com/plugin/6317-lombok-plugin 2. 选择从本地安装.

  2. git命令大杂烩

    查看版本库中的文件: git ls-files添加到暂存区: git add filesName|\folderName(循环递归) git add .(添加当前目录下的所有文件包括子目录,如果添加文 ...

  3. 吧,其实spring自带的BeanUtils就有这样的功能,引入spring-beans和spring-core之后,就有BeanUtils.copyProperties(a, b);可以实现两个javabean之间的相互拷贝,自己写的就当是研究咯---https://www.cnblogs.com/NieXiaoHui/p/7150928.html

    吧,其实spring自带的BeanUtils就有这样的功能,引入spring-beans和spring-core之后,就有BeanUtils.copyProperties(a, b);可以实现两个ja ...

  4. pat甲级 1107. Social Clusters (30)

    When register on a social network, you are always asked to specify your hobbies in order to find som ...

  5. HDU 1228 字符串到数字的转化

    一道水题,练练字符串的输入输出 #include <cstdio> #include <cstring> using namespace std; ] , s2[]; int ...

  6. TCP/IP协议1

    1.分层 应用层 telent 远程登录,ftp 文件传输协议,smtp 简单邮件传送协议 snmp 简单网络管理协议 email 运输层  tcp(提供可靠的数据通信)和udp(数据报的分组从一台主 ...

  7. java 源码分析1 -String

    1. String的本质是一个 char数组,实现了CharSequence 接口, /** The value is used for character storage. */ private f ...

  8. SQL Server 性能优化实战系列(文章索引) : 桦仔

    http://www.cnblogs.com/gaizai/archive/2012/01/20/2327814.html

  9. Behavioral模式之Interpreter模式

    1.意图 给定一个语言,定义它的文法的一种表示.并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 2.别名 无 3.动机 假设一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各种 ...

  10. 通用的Adapter

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...