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. js中细小点

    昨天在写前端代码的时候,遇到一个神奇的问题,我判断序号 num 和数组 arr 的 length 是否相等,如果相等则做想要的处理,伪码如下; if (num === arr.length) { fu ...

  2. BZOJ 1853

    http://www.lydsy.com/JudgeOnline/problem.php?id=1853 岛娘在空间上发的题解就看了看果然被骗了.还以为是数位dp. 原来是容斥啊.好吧第一道正式的题目 ...

  3. [bzoj1607][Usaco2008 Dec]Patting Heads 轻拍牛头_筛法_数学

    Patting Heads 轻拍牛头 bzoj-1607 Usaco-2008 Dec 题目大意:题目链接. 注释:略. 想法:我们发现,位置是没有关系的. 故,我们考虑将权值一样的牛放在一起考虑,c ...

  4. 30、Java并发性和多线程-阿姆达尔定律

    以下内容转自http://ifeve.com/amdahls-law/: 阿姆达尔定律可以用来计算处理器平行运算之后效率提升的能力.阿姆达尔定律因Gene Amdal 在1967年提出这个定律而得名. ...

  5. RESTFUL 和SOA初探

    这篇文章是转载的,restful简单的说就是url明确的指向资源.soa还不好用自己的话解释,但明显不是这样,好吧,我自己的理解就是soa就是访问网站的一个接口.以访问一个blog list为例子,  ...

  6. BMP的图像处理

    近期碰到了一个问题将图片缩放: 进行了整理发现位图一些主要的结构能够进行整理,得出下面图表: 进行图片缩放的时候会进行一些处理(最临近差值法): 详细的代码例如以下: #include <std ...

  7. 如何定义StrokeIt手势 常用StrokeIt手势大全

    1 最小化,最大化,最小化所有(显示桌面) 斜向上表示最大化或者还原,斜向下表示最小化,适用于任务管理器和一般应用程序(有这三个按钮的都可以),先斜向下再斜向上表示显示桌面,这个在WIN7系统中不太实 ...

  8. JavaSE学习笔记--Item1 注解Annotation

    从 JDK 5.0 開始, Java 添加了对元数据(MetaData) 的支持, 也就是 Annotation(注解). 什么是Annotation,以及注解的作用? 三个主要的 Annotatio ...

  9. STL源代码剖析(二) - 迭代器与traits技法

    提要 先看一段用迭代器的代码: int a[] = {1, 2, 3, 4, 5}; vector<int> v1( a, a+5); vector<int>::iterato ...

  10. 安装ubuntu远程桌面xrdp可视化设置界面

    ubuntu 远程桌面的时候须要从系统-首选项-远程桌面 可是有的ubuntu远程桌面的应用须要自己安装.例如以下是安装命令: sudo apt-get install xrdp