Java读取Excel文件汇总
相信很多程序猿朋友碰到上传、读取Excel文件的问题,做个小结,权当是笔记收着吧。
之前做金融报表,是把Excel内嵌到页面中的,技术上采用ZK结合POI读取和插入Excel数据,后台方法比较死,比较程式化。
目前新需求是把Excel表格上传到服务器,读取到里边的数据做处理。
一、首先上传Excel
1、页面添加文件域
<form id="uploadExcel" action="/auth/user/toHandleBatchRobotExcel.do" enctype="multipart/form- data" method="POST" > <input type="file" id="excel" name="excelFile"/> <input type="button" id="uploadExcel" /> </form>
2、使用ajax提交表单(需导入jquery.form.js)
var excel=$("#excel").val(); var location=$('#excel').val(); var point = location.lastIndexOf("."); var type = location.substr(point); //type是Excel表格的格式.xls\.xlsx $("#uploadExcel").ajaxSubmit({ data:{ext:type}, success:function(data){ var dataJson = eval("("+data+")"); console.log(data); if(dataJson.code==100){ alert(dataJson.message); }else{ alert("成功上传"+dataJson.attribute.robotNum+"条记录"); } } });
二、后台读取
我尝试了两种方式来读取,jxl和poi。
1、jxl读取
jxl操作也是比较方便的,上代码吧。
Jar包:jxl-2.6.jar
读取Excel:
@RequestMapping(value = UrlMappings.HANDLE_BATCH_ROBOT_EXCEL, method = RequestMethod.POST) @ResponseBody public void handleExcel(HttpServletResponse response, MultipartHttpServletRequest request, String ext) { logger.info("处理Excel表格"); logger.info("开始解析..."); logger.info(ext); MultipartFile fileFile = request.getFile("excelFile"); InputStream in = fileFile.getInputStream(); //获取Excel文件对象 Workbook wb = Workbook.getWorkbook(in); //获取文件的指定工作表默认的第一个 Sheet sheet = wb.getSheet(0); // 单元格 Cell cell; //获取行数 Int rows = sheet.getRows(); Map<Integer, String> map = new HashMap<Integer, String>(); List<UserInfoVo> list = new LinkedList<UserInfoVo>(); if (rows.size() > 0 && rows!= null) { for (int i = 1; i < rows.size(); i++) { for (int j = 0; j < sheet.getColumns(); j++) { cell =sheet.getCell(j,i); map.put(j,cell.getContents()); } //Excel数据对应的实体类,根据情况自己设定 UserInfoVo userInfoVo = new UserInfoVo(); userInfoVo.setNickName(map.get(1)); userInfoVo.setGender(map.get(2).equals("男") ? 0 : 1); userInfoVo.setBirthday(sdf.parse(map.get(3)).getTime()); userInfoVo.setRegisterDatetime(sdf.parse(map.get(4)) .getTime()); userInfoVo.setState(1); list.add(userInfoVo); } } }
这样读取到的list中就包括了excel表中的各行数据。
但是在使用过程中发现,有些用户上传2007版的Excel表格,这样的话就会出现读取错误的情况
jxl.read.biff.BiffException: Unable to recognize OLE stream,这是因为jxl久未更新,没法读取新版本的 Excel,就是.xlsx格式的文件。
于是,换种思路,使用兼容性更好的poi进行读取。
2、poi读取
poi是读取Excel最佳工具,功能丰富,对读取不同版本的excel都做了对应处理。
jar包:
poi-3.11.jar 针对03版excel,即后缀为.xls的文件。
poi-ooxml-3.11.jar 针对07版excel,即后缀为.xlsx的文件。
读取Excel:
@RequestMapping(value = UrlMappings.HANDLE_BATCH_ROBOT_EXCEL, method = RequestMethod.POST) @ResponseBody public void handleExcel(HttpServletResponse response, MultipartHttpServletRequest request, String ext) { logger.info("处理Excel表格"); logger.info("开始解析..."); //excel格式 .xls\.xlsx logger.info(ext); // 得到上传的文件 MultipartFile fileFile = request.getFile("excelFile"); try { // 转换成输入流 InputStream in = fileFile.getInputStream(); // 单元格 Cell cell; List<Row> rsRows = new ExcelUtils().readExcel(ext, in); // 实例化对象 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); Map<Integer, String> map = new HashMap<Integer, String>(); List<UserInfoVo> list = new LinkedList<UserInfoVo>(); if (rsRows.size() > 0 && rsRows != null) { for (int i = 1; i < rsRows.size(); i++) { for (int j = 0; j < rsRows.get(i).getLastCellNum(); j++) { cell = rsRows.get(i).getCell(j); map.put(j, new ExcelUtils().getCellValue(cell)); } UserInfoVo userInfoVo = new UserInfoVo(); userInfoVo.setNickName(map.get(1)); userInfoVo.setGender(map.get(2).equals("男") ? 0 : 1); userInfoVo.setBirthday(sdf.parse(map.get(3)).getTime()); userInfoVo.setRegisterDatetime(sdf.parse(map.get(4)) .getTime()); userInfoVo.setState(1); list.add(userInfoVo); } } }
List中即是excel表中的数据。这其中要用到一个工具类ExcelUtils。
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; 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 ExcelUtils { // %%%%%%%%-------常量部分 开始----------%%%%%%%%% /** * 默认的开始读取的行位置为第一行(索引值为0) */ private final static int READ_START_POS = 0; /** * 默认结束读取的行位置为最后一行(索引值=0,用负数来表示倒数第n行) */ private final static int READ_END_POS = 0; /** * 默认Excel内容的开始比较列位置为第一列(索引值为0) */ private final static int COMPARE_POS = 0; /** * 默认多文件合并的时需要做内容比较(相同的内容不重复出现) */ private final static boolean NEED_COMPARE = true; /** * 默认多文件合并的新文件遇到名称重复时,进行覆盖 */ private final static boolean NEED_OVERWRITE = true; /** * 默认只操作一个sheet */ private final static boolean ONLY_ONE_SHEET = true; /** * 默认读取第一个sheet中(只有当ONLY_ONE_SHEET = true时有效) */ private final static int SELECTED_SHEET = 0; /** * 默认从第一个sheet开始读取(索引值为0) */ private final static int READ_START_SHEET = 0; /** * 默认在最后一个sheet结束读取(索引值=0,用负数来表示倒数第n行) */ private final static int READ_END_SHEET = 0; /** * 默认打印各种信息 */ private final static boolean PRINT_MSG = true; // %%%%%%%%-------常量部分 结束----------%%%%%%%%% // %%%%%%%%-------字段部分 开始----------%%%%%%%%% /** * Excel文件路径 */ private String excelPath = "data.xlsx"; /** * 设定开始读取的位置,默认为0 */ private int startReadPos = READ_START_POS; /** * 设定结束读取的位置,默认为0,用负数来表示倒数第n行 */ private int endReadPos = READ_END_POS; /** * 设定开始比较的列位置,默认为0 */ private int comparePos = COMPARE_POS; /** * 设定汇总的文件是否需要替换,默认为true */ private boolean isOverWrite = NEED_OVERWRITE; /** * 设定是否需要比较,默认为true(仅当不覆写目标内容是有效,即isOverWrite=false时有效) */ private boolean isNeedCompare = NEED_COMPARE; /** * 设定是否只操作第一个sheet */ private boolean onlyReadOneSheet = ONLY_ONE_SHEET; /** * 设定操作的sheet在索引值 */ private int selectedSheetIdx = SELECTED_SHEET; /** * 设定操作的sheet的名称 */ private String selectedSheetName = ""; /** * 设定开始读取的sheet,默认为0 */ private int startSheetIdx = READ_START_SHEET; /** * 设定结束读取的sheet,默认为0,用负数来表示倒数第n行 */ private int endSheetIdx = READ_END_SHEET; /** * 设定是否打印消息 */ private boolean printMsg = PRINT_MSG; // %%%%%%%%-------字段部分 结束----------%%%%%%%%% public ExcelUtils() { } public ExcelUtils(String excelPath) { this.excelPath = excelPath; } /** * 还原设定(其实是重新new一个新的对象并返回) * * @return */ public ExcelUtils RestoreSettings() { ExcelUtils instance = new ExcelUtils(this.excelPath); return instance; } /** * 自动根据文件扩展名,调用对应的读取方法 * * @Title: writeExcel * @Date : 2014-9-11 下午01:50:38 * @throws IOException */ public List<Row> readExcel() throws IOException { return readExcel(this.excelPath); } /** * 自动根据文件扩展名,调用对应的读取方法 * * @Title: writeExcel * @Date : 2014-9-11 下午01:50:38 * @param xlsPath * @throws IOException */ public List<Row> readExcel(String xlsPath) throws IOException { // 扩展名为空时, if (xlsPath.equals("")) { throw new IOException("文件路径不能为空!"); } else { File file = new File(xlsPath); if (!file.exists()) { throw new IOException("文件不存在!"); } } // 获取扩展名 String ext = xlsPath.substring(xlsPath.lastIndexOf(".") + 1); try { if ("xls".equals(ext)) { // 使用xls方式读取 return readExcel_xls(xlsPath); } else if ("xlsx".equals(ext)) { // 使用xlsx方式读取 return readExcel_xlsx(xlsPath); } else { // 依次尝试xls、xlsx方式读取 out("您要操作的文件没有扩展名,正在尝试以xls方式读取..."); try { return readExcel_xls(xlsPath); } catch (IOException e1) { out("尝试以xls方式读取,结果失败!,正在尝试以xlsx方式读取..."); try { return readExcel_xlsx(xlsPath); } catch (IOException e2) { out("尝试以xls方式读取,结果失败!\n请您确保您的文件是Excel文件,并且无损,然后再试。"); throw e2; } } } } catch (IOException e) { throw e; } } /** * 通过判断文件的扩展名,以不同的方式读取文件 * * @author wufei 2016年9月19日 上午10:41:27 * @Method: readExcel * @Description: TODO * @param @param ext * @param @param in * @param @return * @param @throws IOException * @return List<Row> * @throws */ public List<Row> readExcel(String ext, InputStream in) { try { if (".xls".equals(ext)) { // 使用xls方式读取 return readExcel_xlsAsStream(in); } else if (".xlsx".equals(ext)) { // 使用xlsx方式读取 return readExcel_xlsxAsStream(in); } else { // 依次尝试xls、xlsx方式读取 out("您要操作的文件没有扩展名,正在尝试以xlsx方式读取..."); try { return readExcel_xlsxAsStream(in); } catch (Exception e1) { out("尝试以xlsx方式读取,结果失败!,正在尝试以xls方式读取..."); try { return readExcel_xlsAsStream(in); } catch (IOException e2) { out("尝试以xls方式读取,结果失败!\n请您确保您的文件是Excel文件,并且无损,然后再试。"); throw e2; } } } } catch (IOException e) { out(e.getMessage()); return null; } } /** * 自动根据文件扩展名,调用对应的写入方法 * * @Title: writeExcel * @Date : 2014-9-11 下午01:50:38 * @param rowList * @throws IOException */ public void writeExcel(List<Row> rowList) throws IOException { writeExcel(rowList, excelPath); } /** * 自动根据文件扩展名,调用对应的写入方法 * * @Title: writeExcel * @Date : 2014-9-11 下午01:50:38 * @param rowList * @param xlsPath * @throws IOException */ public void writeExcel(List<Row> rowList, String xlsPath) throws IOException { // 扩展名为空时, if (xlsPath.equals("")) { throw new IOException("文件路径不能为空!"); } // 获取扩展名 String ext = xlsPath.substring(xlsPath.lastIndexOf(".") + 1); try { if ("xls".equals(ext)) { // 使用xls方式写入 writeExcel_xls(rowList, xlsPath); } else if ("xlsx".equals(ext)) { // 使用xlsx方式写入 writeExcel_xlsx(rowList, xlsPath); } else { // 依次尝试xls、xlsx方式写入 out("您要操作的文件没有扩展名,正在尝试以xls方式写入..."); try { writeExcel_xls(rowList, xlsPath); } catch (IOException e1) { out("尝试以xls方式写入,结果失败!,正在尝试以xlsx方式读取..."); try { writeExcel_xlsx(rowList, xlsPath); } catch (IOException e2) { out("尝试以xls方式写入,结果失败!\n请您确保您的文件是Excel文件,并且无损,然后再试。"); throw e2; } } } } catch (IOException e) { throw e; } } /** * 修改Excel(97-03版,xls格式) * * @Title: writeExcel_xls * @Date : 2014-9-11 下午01:50:38 * @param rowList * @param dist_xlsPath * @throws IOException */ public void writeExcel_xls(List<Row> rowList, String dist_xlsPath) throws IOException { writeExcel_xls(rowList, excelPath, dist_xlsPath); } /** * 修改Excel(97-03版,xls格式) * * @Title: writeExcel_xls * @Date : 2014-9-11 下午01:50:38 * @param rowList * @param src_xlsPath * @param dist_xlsPath * @throws IOException */ public void writeExcel_xls(List<Row> rowList, String src_xlsPath, String dist_xlsPath) throws IOException { // 判断文件路径是否为空 if (dist_xlsPath == null || dist_xlsPath.equals("")) { out("文件路径不能为空"); throw new IOException("文件路径不能为空"); } // 判断文件路径是否为空 if (src_xlsPath == null || src_xlsPath.equals("")) { out("文件路径不能为空"); throw new IOException("文件路径不能为空"); } // 判断列表是否有数据,如果没有数据,则返回 if (rowList == null || rowList.size() == 0) { out("文档为空"); return; } try { HSSFWorkbook wb = null; // 判断文件是否存在 File file = new File(dist_xlsPath); if (file.exists()) { // 如果复写,则删除后 if (isOverWrite) { file.delete(); // 如果文件不存在,则创建一个新的Excel // wb = new HSSFWorkbook(); // wb.createSheet("Sheet1"); wb = new HSSFWorkbook(new FileInputStream(src_xlsPath)); } else { // 如果文件存在,则读取Excel wb = new HSSFWorkbook(new FileInputStream(file)); } } else { // 如果文件不存在,则创建一个新的Excel // wb = new HSSFWorkbook(); // wb.createSheet("Sheet1"); wb = new HSSFWorkbook(new FileInputStream(src_xlsPath)); } // 将rowlist的内容写到Excel中 writeExcel(wb, rowList, dist_xlsPath); } catch (IOException e) { e.printStackTrace(); } } /** * 修改Excel(97-03版,xls格式) * * @Title: writeExcel_xls * @Date : 2014-9-11 下午01:50:38 * @param rowList * @param dist_xlsPath * @throws IOException */ public void writeExcel_xlsx(List<Row> rowList, String dist_xlsPath) throws IOException { writeExcel_xls(rowList, excelPath, dist_xlsPath); } /** * 修改Excel(2007版,xlsx格式) * * @Title: writeExcel_xlsx * @Date : 2014-9-11 下午01:50:38 * @param rowList * @throws IOException */ public void writeExcel_xlsx(List<Row> rowList, String src_xlsPath, String dist_xlsPath) throws IOException { // 判断文件路径是否为空 if (dist_xlsPath == null || dist_xlsPath.equals("")) { out("文件路径不能为空"); throw new IOException("文件路径不能为空"); } // 判断文件路径是否为空 if (src_xlsPath == null || src_xlsPath.equals("")) { out("文件路径不能为空"); throw new IOException("文件路径不能为空"); } // 判断列表是否有数据,如果没有数据,则返回 if (rowList == null || rowList.size() == 0) { out("文档为空"); return; } try { // 读取文档 HSSFWorkbook wb = null; // 判断文件是否存在 File file = new File(dist_xlsPath); if (file.exists()) { // 如果复写,则删除后 if (isOverWrite) { file.delete(); // 如果文件不存在,则创建一个新的Excel // wb = new XSSFWorkbook(); // wb.createSheet("Sheet1"); wb = new HSSFWorkbook(new FileInputStream(src_xlsPath)); } else { // 如果文件存在,则读取Excel wb = new HSSFWorkbook(new FileInputStream(file)); } } else { // 如果文件不存在,则创建一个新的Excel // wb = new XSSFWorkbook(); // wb.createSheet("Sheet1"); wb = new HSSFWorkbook(new FileInputStream(src_xlsPath)); } // 将rowlist的内容添加到Excel中 writeExcel(wb, rowList, dist_xlsPath); } catch (IOException e) { e.printStackTrace(); } } /** * //读取Excel 2007版,xlsx格式 * * @Title: readExcel_xlsx * @Date : 2014-9-11 上午11:43:11 * @return * @throws IOException */ public List<Row> readExcel_xlsx() throws IOException { return readExcel_xlsx(excelPath); } /** * //读取Excel 2007版,xlsx格式 * * @Title: readExcel_xlsx * @Date : 2014-9-11 上午11:43:11 * @return * @throws Exception */ public List<Row> readExcel_xlsx(String xlsPath) throws IOException { // 判断文件是否存在 File file = new File(xlsPath); if (!file.exists()) { throw new IOException("文件名为" + file.getName() + "Excel文件不存在!"); } XSSFWorkbook wb = null; List<Row> rowList = new ArrayList<Row>(); try { FileInputStream fis = new FileInputStream(file); // 去读Excel wb = new XSSFWorkbook(fis); // 读取Excel 2007版,xlsx格式 rowList = readExcel(wb); } catch (IOException e) { e.printStackTrace(); } return rowList; } /** * 以流的形式读取excel文件 2007版xlsx * * @author wufei 2016年9月19日 上午10:35:40 * @Method: readExcel_xlsxAsStream * @Description: TODO * @param @param in * @param @return * @param @throws IOException * @return List<Row> * @throws */ public List<Row> readExcel_xlsxAsStream(InputStream in) throws IOException { XSSFWorkbook wb = null; List<Row> rowList = new ArrayList<Row>(); try { // 去读Excel wb = new XSSFWorkbook(in); // 读取Excel 2007版,xlsx格式 rowList = readExcel(wb); } catch (IOException e) { e.printStackTrace(); } return rowList; } /*** * 读取Excel(97-03版,xls格式) * * @throws IOException * * @Title: readExcel * @Date : 2014-9-11 上午09:53:21 */ public List<Row> readExcel_xls() throws IOException { return readExcel_xls(excelPath); } /*** * 读取Excel(97-03版,xls格式) * * @throws Exception * * @Title: readExcel * @Date : 2014-9-11 上午09:53:21 */ public List<Row> readExcel_xls(String xlsPath) throws IOException { // 判断文件是否存在 File file = new File(xlsPath); if (!file.exists()) { throw new IOException("文件名为" + file.getName() + "Excel文件不存在!"); } HSSFWorkbook wb = null;// 用于Workbook级的操作,创建、删除Excel List<Row> rowList = new ArrayList<Row>(); try { // 读取Excel wb = new HSSFWorkbook(new FileInputStream(file)); // 读取Excel 97-03版,xls格式 rowList = readExcel(wb); } catch (IOException e) { e.printStackTrace(); } return rowList; } /** * 以流的形式读取97-03版excel文件 * * @author wufei 2016年9月19日 上午10:33:25 * @Method: readExcel_xlsAsStream * @Description: TODO * @param @param in * @param @return * @param @throws IOException * @return List<Row> * @throws */ public List<Row> readExcel_xlsAsStream(InputStream in) throws IOException { HSSFWorkbook wb = null;// 用于Workbook级的操作,创建、删除Excel List<Row> rowList = new ArrayList<Row>(); try { // 读取Excel wb = new HSSFWorkbook(in); // 读取Excel 97-03版,xls格式 rowList = readExcel(wb); } catch (IOException e) { e.printStackTrace(); } return rowList; } /*** * 读取单元格的值 * * @Title: getCellValue * @Date : 2014-9-11 上午10:52:07 * @param cell * @return */ public String getCellValue(Cell cell) { Object result = ""; if (cell != null) { switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: result = cell.getStringCellValue(); break; case Cell.CELL_TYPE_NUMERIC: // 判断是否为日期 if (HSSFDateUtil.isCellDateFormatted(cell)) { SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd"); Date date = HSSFDateUtil.getJavaDate(cell .getNumericCellValue()); result = df.format(date); } else { result = cell.getNumericCellValue(); } break; case Cell.CELL_TYPE_BOOLEAN: result = cell.getBooleanCellValue(); break; case Cell.CELL_TYPE_FORMULA: result = cell.getCellFormula(); break; case Cell.CELL_TYPE_ERROR: result = cell.getErrorCellValue(); break; case Cell.CELL_TYPE_BLANK: break; default: break; } } return result.toString(); } /** * 通用读取Excel * * @Title: readExcel * @Date : 2014-9-11 上午11:26:53 * @param wb * @return */ private List<Row> readExcel(Workbook wb) { List<Row> rowList = new ArrayList<Row>(); int sheetCount = 1;// 需要操作的sheet数量 Sheet sheet = null; if (onlyReadOneSheet) { // 只操作一个sheet // 获取设定操作的sheet(如果设定了名称,按名称查,否则按索引值查) sheet = selectedSheetName.equals("") ? wb .getSheetAt(selectedSheetIdx) : wb .getSheet(selectedSheetName); } else { // 操作多个sheet sheetCount = wb.getNumberOfSheets();// 获取可以操作的总数量 } // 获取sheet数目 for (int t = startSheetIdx; t < sheetCount + endSheetIdx; t++) { // 获取设定操作的sheet if (!onlyReadOneSheet) { sheet = wb.getSheetAt(t); } // 获取最后行号 int lastRowNum = sheet.getLastRowNum(); if (lastRowNum > 0) { // 如果>0,表示有数据 out("\n开始读取名为【" + sheet.getSheetName() + "】的内容:"); } Row row = null; // 循环读取 for (int i = startReadPos; i <= lastRowNum + endReadPos; i++) { row = sheet.getRow(i); if (row != null) { rowList.add(row); out("第" + (i + 1) + "行:", false); // 获取每一单元格的值 for (int j = 0; j < row.getLastCellNum(); j++) { String value = getCellValue(row.getCell(j)); if (!value.equals("")) { out(value + " | ", false); } } out(""); } } } return rowList; } /** * 修改Excel,并另存为 * * @Title: WriteExcel * @Date : 2014-9-11 下午01:33:59 * @param wb * @param rowList * @param xlsPath */ private void writeExcel(Workbook wb, List<Row> rowList, String xlsPath) { if (wb == null) { out("操作文档不能为空!"); return; } Sheet sheet = wb.getSheetAt(0);// 修改第一个sheet中的值 // 如果每次重写,那么则从开始读取的位置写,否则果获取源文件最新的行。 int lastRowNum = isOverWrite ? startReadPos : sheet.getLastRowNum() + 1; int t = 0;// 记录最新添加的行数 out("要添加的数据总条数为:" + rowList.size()); for (Row row : rowList) { if (row == null) continue; // 判断是否已经存在该数据 int pos = findInExcel(sheet, row); Row r = null;// 如果数据行已经存在,则获取后重写,否则自动创建新行。 if (pos >= 0) { sheet.removeRow(sheet.getRow(pos)); r = sheet.createRow(pos); } else { r = sheet.createRow(lastRowNum + t++); } // 用于设定单元格样式 CellStyle newstyle = wb.createCellStyle(); // 循环为新行创建单元格 for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { Cell cell = r.createCell(i);// 获取数据类型 cell.setCellValue(getCellValue(row.getCell(i)));// 复制单元格的值到新的单元格 // cell.setCellStyle(row.getCell(i).getCellStyle());//出错 if (row.getCell(i) == null) continue; copyCellStyle(row.getCell(i).getCellStyle(), newstyle); // 获取原来的单元格样式 cell.setCellStyle(newstyle);// 设置样式 // sheet.autoSizeColumn(i);//自动跳转列宽度 } } out("其中检测到重复条数为:" + (rowList.size() - t) + " ,追加条数为:" + t); // 统一设定合并单元格 setMergedRegion(sheet); try { // 重新将数据写入Excel中 FileOutputStream outputStream = new FileOutputStream(xlsPath); wb.write(outputStream); outputStream.flush(); outputStream.close(); } catch (Exception e) { out("写入Excel时发生错误! "); e.printStackTrace(); } } /** * 查找某行数据是否在Excel表中存在,返回行数。 * * @Title: findInExcel * @Date : 2014-9-11 下午02:23:12 * @param sheet * @param row * @return */ private int findInExcel(Sheet sheet, Row row) { int pos = -1; try { // 如果覆写目标文件,或者不需要比较,则直接返回 if (isOverWrite || !isNeedCompare) { return pos; } for (int i = startReadPos; i <= sheet.getLastRowNum() + endReadPos; i++) { Row r = sheet.getRow(i); if (r != null && row != null) { String v1 = getCellValue(r.getCell(comparePos)); String v2 = getCellValue(row.getCell(comparePos)); if (v1.equals(v2)) { pos = i; break; } } } } catch (Exception e) { e.printStackTrace(); } return pos; } /** * 复制一个单元格样式到目的单元格样式 * * @param fromStyle * @param toStyle */ public static void copyCellStyle(CellStyle fromStyle, CellStyle toStyle) { toStyle.setAlignment(fromStyle.getAlignment()); // 边框和边框颜色 toStyle.setBorderBottom(fromStyle.getBorderBottom()); toStyle.setBorderLeft(fromStyle.getBorderLeft()); toStyle.setBorderRight(fromStyle.getBorderRight()); toStyle.setBorderTop(fromStyle.getBorderTop()); toStyle.setTopBorderColor(fromStyle.getTopBorderColor()); toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor()); toStyle.setRightBorderColor(fromStyle.getRightBorderColor()); toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor()); // 背景和前景 toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor()); toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor()); // 数据格式 toStyle.setDataFormat(fromStyle.getDataFormat()); toStyle.setFillPattern(fromStyle.getFillPattern()); // toStyle.setFont(fromStyle.getFont(null)); toStyle.setHidden(fromStyle.getHidden()); toStyle.setIndention(fromStyle.getIndention());// 首行缩进 toStyle.setLocked(fromStyle.getLocked()); toStyle.setRotation(fromStyle.getRotation());// 旋转 toStyle.setVerticalAlignment(fromStyle.getVerticalAlignment()); toStyle.setWrapText(fromStyle.getWrapText()); } /** * 获取合并单元格的值 * * @param sheet * @return */ public void setMergedRegion(Sheet sheet) { int sheetMergeCount = sheet.getNumMergedRegions(); for (int i = 0; i < sheetMergeCount; i++) { // 获取合并单元格位置 CellRangeAddress ca = sheet.getMergedRegion(i); int firstRow = ca.getFirstRow(); if (startReadPos - 1 > firstRow) {// 如果第一个合并单元格格式在正式数据的上面,则跳过。 continue; } int lastRow = ca.getLastRow(); int mergeRows = lastRow - firstRow;// 合并的行数 int firstColumn = ca.getFirstColumn(); int lastColumn = ca.getLastColumn(); // 根据合并的单元格位置和大小,调整所有的数据行格式, for (int j = lastRow + 1; j <= sheet.getLastRowNum(); j++) { // 设定合并单元格 sheet.addMergedRegion(new CellRangeAddress(j, j + mergeRows, firstColumn, lastColumn)); j = j + mergeRows;// 跳过已合并的行 } } } /** * 打印消息, * * @param msg * 消息内容 换行 */ private void out(String msg) { if (printMsg) { out(msg, true); } } /** * 打印消息, * * @param msg * 消息内容 * @param tr * 换行 */ private void out(String msg, boolean tr) { if (printMsg) { System.out.print(msg + (tr ? "\n" : "")); } } public String getExcelPath() { return this.excelPath; } public void setExcelPath(String excelPath) { this.excelPath = excelPath; } public boolean isNeedCompare() { return isNeedCompare; } public void setNeedCompare(boolean isNeedCompare) { this.isNeedCompare = isNeedCompare; } public int getComparePos() { return comparePos; } public void setComparePos(int comparePos) { this.comparePos = comparePos; } public int getStartReadPos() { return startReadPos; } public void setStartReadPos(int startReadPos) { this.startReadPos = startReadPos; } public int getEndReadPos() { return endReadPos; } public void setEndReadPos(int endReadPos) { this.endReadPos = endReadPos; } public boolean isOverWrite() { return isOverWrite; } public void setOverWrite(boolean isOverWrite) { this.isOverWrite = isOverWrite; } public boolean isOnlyReadOneSheet() { return onlyReadOneSheet; } public void setOnlyReadOneSheet(boolean onlyReadOneSheet) { this.onlyReadOneSheet = onlyReadOneSheet; } public int getSelectedSheetIdx() { return selectedSheetIdx; } public void setSelectedSheetIdx(int selectedSheetIdx) { this.selectedSheetIdx = selectedSheetIdx; } public String getSelectedSheetName() { return selectedSheetName; } public void setSelectedSheetName(String selectedSheetName) { this.selectedSheetName = selectedSheetName; } public int getStartSheetIdx() { return startSheetIdx; } public void setStartSheetIdx(int startSheetIdx) { this.startSheetIdx = startSheetIdx; } public int getEndSheetIdx() { return endSheetIdx; } public void setEndSheetIdx(int endSheetIdx) { this.endSheetIdx = endSheetIdx; } public boolean isPrintMsg() { return printMsg; } public void setPrintMsg(boolean printMsg) { this.printMsg = printMsg; } }
至此,读取完毕。
相关推荐
在Java编程中,解析Excel文件是一项常见的任务,特别是在数据处理、报表生成或数据分析等领域。Excel文件格式主要有两种:老式的`.xls`(基于BIFF格式)和较新的`.xlsx`(基于Open XML标准)。本篇将详细介绍如何...
接下来,我们需要创建一个Java程序来读取Excel文件。使用POI的`XSSFWorkbook`类打开Excel文件,然后通过` XSSFSheet `获取工作表,并使用` XSSFRow `和` XSSFCell `遍历单元格数据: ```java import org.apache.poi...
本篇文章介绍了一个方法,该方法能够读取Excel文件并将其中的数据存储到Java中的`Map`集合里,便于后续进行数据分析或处理。 #### 方法概述 方法签名如下: ```java public Map, Map, String>> importReportExcel...
在本文中,我们将详细介绍基于Java Excel API的excel文件的操纵技术,包括excel文件的读取和写入、excel文件的编辑和格式化、excel文件的打印和导出等内容。此外,我们还将提供一些实用的示例代码,以便读者更好地...
它提供了一组API,允许开发者在Java应用程序中读写Microsoft Office格式的文件,如Excel和Word文档。 - **特点**: - **广泛支持**:支持多种Office文件格式。 - **成熟稳定**:作为一个成熟的项目,POI在业界...
这个场景下,我们需要使用Java来统计多个Excel文档中的数据,并根据月份进行分类统计,最后将结果汇总到一个新的Excel文件中。以下是一些相关的知识点和实现步骤: 1. **Java库的选择**: - Apache POI:这是一个...
根据给定文件中的标题、描述、标签以及部分内容,可以总结并扩展出以下关于 Java Excel API 的相关知识点: ### Java Excel API 常用类库 #### jxl.jar `jxl.jar` 是一个用于处理 Excel 文件的 Java 库。它支持 ...
Apache POI 是一个流行的开源库,它允许Java开发者读写Microsoft Office格式的文件,包括Excel(.xlsx 和 .xls)。本教程将详细介绍如何使用Apache POI结合注解的方式进行Excel的导入与导出。 首先,导入Apache POI...
Java POI是Apache软件基金会下的一个开源项目,主要用于读写Microsoft Office格式的文件,特别是Excel。在Java开发中,当你需要处理Excel数据时,POI库是一个强大的工具。本压缩包包含了一些关键资源,帮助你理解和...
利用Apache POI库能够实现这一功能,即可以通过Java程序操作Excel文件,包括读取、写入、以及处理Excel中的公式。 #### 二、关键技术点 1. **POI库简介**: - Apache POI是Apache软件基金会的Jakarta项目中的一个...
综上所述,"EXcel汇总"工具是一款针对Excel2003和Excel2007版本设计的文件合并工具,它利用Java编程语言实现跨平台运行,能有效整合格式相同或相近的Excel文件,提高数据处理效率,减少人为错误。通过理解并掌握这样...
- **概述**:OpenXML4J 是一个基于Java的开源库,它允许开发者轻松地创建、读取和修改Microsoft Office Open XML 格式的文档,如Word (.docx)、Excel (.xlsx) 和 PowerPoint (.pptx) 文件。 - **主要特性**: - ...
这类工具通常能读取大文件,然后按每个工作表创建新的独立Excel文件。 3. 分割步骤: - 打开分割工具:运行`SplitExcel.exe`,根据工具的界面提示进行操作。 - 选择源文件:找到并加载你需要拆分的超大Excel文件...
- Apache POI:这是一个流行的Java API,用于读写Microsoft Office格式的文件,包括Excel。主要类有`XSSFWorkbook`(用于创建.xlsx文件)和`HSSFWorkbook`(用于创建.xls文件)。 - OpenCSV:虽然主要处理CSV文件...
以下是一个简单的示例,展示如何从多个xls文件中读取数据并将其汇总到一个新的文件中: 1. **准备工作**: - 将jxl.jar库添加到项目的构建路径或类路径中。 - 创建一个名为`RWExcel`的自定义类,用于封装xls文件...
1. **JXL库**: JXL是Java的一个库,用于读写Excel文件。它允许开发者在Java程序中创建、修改和读取Excel工作簿。通过JXL,你可以创建新的工作表,设置单元格样式,读取数据,进行公式计算,并且处理图表,这对于数据...
在Java编程语言中,处理文档,尤其...综上所述,Java结合Apache POI库能够高效地进行Excel文档的读写操作,实现报表的统计与汇总。在实际开发中,根据需求选择合适的API,并注意性能优化,可以提高代码的稳定性和效率。
POI(Poor Obfuscation Implementation)是一个Java API,用于读取和写入Microsoft Office文件格式,包括Excel文件。 首先,需要设计Excel报表模板,并将其保存为report.xls文件。该报表模板具有复杂的表头,第四...
另一种选择是使用EPPlus库,它可以处理.xlsx文件,并提供了一种轻量级的方式来读写Excel数据。 Excel Lib 还可能涉及到的数据处理概念包括: 1. 工作簿(Workbook):Excel文件中的最高级别容器,包含一个或多个...
在Java中,我们可以利用Apache POI库来实现Excel文件的读取、写入和操作,包括创建透视表。Apache POI是一个开源项目,提供了API来处理Microsoft Office格式的文件,如XLS(Excel 97-2003)和XLSX(Excel 2007及以上...