Java Controller下兼容xls和xlsx且可识别合并单元格的excel导入功能
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导入功能的更多相关文章
- java导出标题多行且合并单元格的EXCEL
场景:项目中遇到有需要导出Excel的需求,并且是多行标题且有合并单元格的,参考网上的文章,加上自己的理解,封装成了可自由扩展的导出工具 先上效果,再贴代码: 调用工具类进行导出: public st ...
- Java解析Excel工具类(兼容xls和xlsx)
依赖jar <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml&l ...
- PHPEXCEL xls模板导入,及格式自定义:合并单元格、加粗、居中等操作
PHPExcel 是用来操作Office Excel 文档的一个PHP类库,它基于微软的OpenXML标准和PHP语言.可以使用它来读取.写入不同格式的电子表格,如 Excel (BIFF) .xls ...
- java合并单元格同时导出excel
POI进行跨行需要用到对象HSSFSheet对象,现在就当我们程序已经定义了一个HSSFSheet对象sheet. 跨第1行第1个到第2个单元格的操作为 sheet.addMergedRegion(n ...
- python3-xlwt-Excel设置(字体大小、颜色、对齐方式、换行、合并单元格、边框、背景、下划线、斜体、加粗)
搬运出处: https://blog.csdn.net/weixin_44065501/article/details/88899257 # coding:utf-8 import patterns ...
- Java删除word合并单元格时的重复值
Spire.Doc提供了Table.applyVerticalMerge()方法来垂直合并word文档里面的表格单元格,Table.applyHorizontalMerge()方法来水平合并表格单元格 ...
- java使用freemarker模板导出word(带有合并单元格)文档
来自:https://blog.csdn.net/qq_33195578/article/details/73790283 前言:最近要做一个导出word功能,其实网上有很多的例子,但是我需要的是合并 ...
- java poi 合并单元格
java poi 合并单元格 2017年03月29日 16:39:01 翠烟你懊恼 阅读数:26561 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.n ...
- Java导出Excel表,POI 实现合并单元格以及列自适应宽度(转载)
POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...
随机推荐
- hdu 1867 kmp匹配
#include<stdio.h> #include<string.h> #define N 100100 void getnext(int next[],char s[]) ...
- cogs——1298. 通讯问题
1298. 通讯问题 ★★ 输入文件:jdltt.in 输出文件:jdltt.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 一个篮球队有n个篮球队员,每个队员 ...
- 【CV论文阅读】Going deeper with convolutions(GoogLeNet)
目的: 提升深度神经网络的性能. 一般方法带来的问题: 增加网络的深度与宽度. 带来两个问题: (1)参数增加,数据不足的情况容易导致过拟合 (2)计算资源要求高,而且在训练过程中会使得很多参数趋向于 ...
- bbed改动undo段状态(ORA-01578)
ZBDBA@orcl11g>select * from zbdba; select * from zbdba * ERROR at line 1: ORA-01578: ORACLE data ...
- 【翻译自mos文章】OGG replicat 进程使用的 TCP port
OGG replicat 进程使用的 TCP port 来源于: TCP PORT USED BY REPLICAT PROCESSES (文档 ID 1060954.1) 适用于: Oracle G ...
- Linuxserver沦陷为肉鸡的全过程实录
Linuxserver沦陷为肉鸡的全过程实录 Linuxserver沦陷为肉鸡的全过程实录 从防火墙瘫痪说起 查找黑客行踪的方法 沦陷过程分析 1 oracle用户password被破解 2 黑客动作 ...
- svn 运行clear up 失败的解决的方法
SVN 的clear up命令失败的解决方法 1. 下载 sqlite3.exe 文件,放到d盘根文件夹. (能够到这里下载 http://download.csdn.net/detail ...
- DeepDive is a system to extract value from dark data.
DeepDive is a system to extract value from dark data. http://deepdive.stanford.edu/
- 【Poj2960】S-Nim & 博弈论
Position: http://poj.org/problem?id=2960 List Poj2960 S-Nim List Description Knowledge Solution Noti ...
- WebView播放H5课件时,锁屏解锁后,页面重新绘制的问题
难题描述:H5页面播放 ,锁屏,解锁后,重新加载了页面,三星不会出现(onpause onstop ,onresume),但在小米.魅族会调用 onpause onstop ondestroy,onr ...