由于java流无法实现对Excel文件的读写操作,因此在项目中经常利用第三方开源的组件来实现。支持Excel文件操作的第三方开源组件主要有Apache的POI和开源社区的JXL。
总体来说,二者的区别是:JXL较为轻量级,如果是对Excel文件的简单操作,建议使用JXL;POI的功能相当强大,但同时处理问题也相当的繁琐。
1.准备工作
【必需】下载JXL的jar包:jxl.jar
【非必需】JXL API (提取密码:zgqj)
2.一些必要的说明
主要是对Excel结构的说明:
- Excel后缀为xls或者xlsx —— Excel文件对应JXL的WritableWorkbook类。
- Excel中可以有多个工作表(也就是左下角的sheet*,见下表) —— 对应JXL的WritableSheet类。
- Excel单元格相当于矩阵,有自己的行、列 —— 对应JXL的Cell类。
3.开始编程
封装了4个方法:
public static void writeExcel(String fileName); —— 写Excel文件
public static String readExcel(File file); —— 读取Excel文件
public static Boolean searchKeyWord(File file, String keyWord); —— 搜索Excel文件中是否包含关键字
public static void insertImage(WritableSheet sheet,int col, int row,int width, int height,File imageFile); —— 向Excel中插入图片(仅限png格式的图片,其余格式如jgp、gif等暂不支持)
1 package com.myeclipse; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import jxl.Cell; 7 import jxl.Sheet; 8 import jxl.Workbook; 9 import jxl.read.biff.BiffException; 10 import jxl.write.Label; 11 import jxl.write.WritableImage; 12 import jxl.write.WritableSheet; 13 import jxl.write.WritableWorkbook; 14 import jxl.write.WriteException; 15 import jxl.write.biff.RowsExceededException; 16 17 /** 18 * 使用JXL对Excel文件进行操作 19 * @author MrChen 20 * 21 */ 22 public class JXLOperateExcel { 23 /** 24 * 写入Excel 25 * @param fileName 要生成的Excel文件名字 26 */ 27 public static void writeExcel(String fileName) { 28 //1.使用Workbook类的工厂方法创建一个可写入的工作薄(Workbook)对象 29 WritableWorkbook wwb = null; 30 try { 31 wwb = Workbook.createWorkbook(new File(fileName)); 32 } catch (IOException e) { 33 e.printStackTrace(); 34 } 35 36 if(wwb == null) { 37 return; 38 } 39 40 //2.创建一个可写入的工作表 41 //workbook的createSheet方法有两个参数:第一个是工作表的名称,第二个是工作表在工作薄中的位置 42 WritableSheet sheet = wwb.createSheet("sheet1", 0); 43 44 //3.添加单元格 45 for(int i=0; i<10; i++) { 46 for(int j=0; j<5; j++) { 47 //Label label = new Label(col, row, title); 48 //三个参数分别表示col+1列,row+1行,标题内容是title。 49 Label label = new Label(j, i, "这是第"+(i+1)+"行,第"+(j+1)+"列"); 50 51 //将生成的单元格添加到工作表中 52 try { 53 sheet.addCell(label); 54 } catch (RowsExceededException e) { 55 e.printStackTrace(); 56 } catch (WriteException e) { 57 e.printStackTrace(); 58 } 59 60 } 61 } 62 63 try { 64 //4.从内存写入到文件中 65 wwb.write(); 66 //5.关闭资源,释放内存 67 wwb.close(); 68 } catch (WriteException e) { 69 e.printStackTrace(); 70 } catch (IOException e) { 71 e.printStackTrace(); 72 } 73 74 } 75 76 /** 77 * 读取Excel文件 78 * @param file 要读取的Excel文件 79 * @return Excel每个单元格的内容(按照一定格式) 80 */ 81 public static String readExcel(File file) { 82 StringBuffer sb = new StringBuffer(); 83 Workbook wb = null; 84 //1.获取工作薄对象(Workbook) 85 try { 86 wb = Workbook.getWorkbook(file); 87 } catch (BiffException e) { 88 e.printStackTrace(); 89 } catch (IOException e) { 90 e.printStackTrace(); 91 } 92 if(wb==null) { 93 return null; 94 } 95 96 //2.得到工作表对象(Sheet) 97 Sheet[] sheets = wb.getSheets(); 98 99 //3.循环操作单元格 100 if(sheets!=null && sheets.length>0) { 101 //对每个工作表进行循环 102 for(int i=0; i<sheets.length; i++) { 103 //得到当前工作表的行数 104 int rowNum = sheets[i].getRows(); 105 for(int j=0; j<rowNum; j++) { 106 //得到当前行的所有单元格 107 Cell[] cells = sheets[i].getRow(j); 108 if(cells != null && cells.length > 0) { 109 //对每个单元格进行循环 110 for(int k=0; k<cells.length; k++) { 111 //读取当前单元格的值 112 String cellValue = cells[k].getContents(); 113 sb.append(cellValue+"\t"); 114 } 115 } 116 sb.append("\r\n"); 117 } 118 sb.append("\r\n"); 119 } 120 } 121 122 //4.关闭资源,释放内存 123 wb.close(); 124 return sb.toString(); 125 } 126 127 /** 128 * 搜索Excel文件中是否包含关键字 129 * @param file 要搜索的Excel文件 130 * @param keyWord 要搜索的关键字 131 * @return 是否包含关键字 132 */ 133 public static Boolean searchKeyWord(File file, String keyWord) { 134 //构建一个开关,用来保存搜索成功与否的状态 135 Boolean res = false; 136 Workbook wb = null; 137 //1.获取工作薄对象(Workbook) 138 try { 139 wb = Workbook.getWorkbook(file); 140 } catch (BiffException e) { 141 e.printStackTrace(); 142 } catch (IOException e) { 143 e.printStackTrace(); 144 } 145 if(wb == null) { 146 return res; 147 } 148 149 //2.得到工作表对象(Sheet) 150 Sheet[] sheets = wb.getSheets(); 151 if(sheets == null || sheets.length == 0) { 152 return res; 153 } 154 155 //3.循环比对单元格 156 Boolean breakSheet = false; //开关 157 for(int i=0; i<sheets.length; i++) { 158 if( breakSheet ) { 159 break; 160 } 161 162 //得到当前工作表的行数 163 Integer rowNum = sheets[i].getRows(); 164 Boolean breakRow = false; 165 for(int j=0; j<rowNum; j++) { 166 if(breakRow) { 167 break; 168 } 169 //得到当前行的所有单元格 170 Cell[] cells = sheets[i].getRow(j); 171 if(cells==null || sheets.length==0) { 172 return res; 173 } 174 //对每个单元格进行循环 175 Boolean breakCell = false; 176 for(int k=0; k<cells.length; k++) { 177 if(breakCell){ 178 break; 179 } 180 //读取当前单元格的值 181 String cellValue = cells[k].getContents(); 182 if(cellValue == null) { 183 continue; 184 } 185 if(cellValue.contains(keyWord)) { 186 breakCell = true; 187 breakRow = true; 188 breakSheet = true; 189 res = true; 190 } 191 } 192 } 193 } 194 //4.关闭资源,释放内存 195 wb.close(); 196 return res; 197 } 198 199 /** 200 * 向Excel中插入图片(仅限png格式的图片,其余格式如jgp、gif等暂不支持) 201 * @param sheet 待插入的工作表 202 * @param col 图片从该列开始 203 * @param row 图片从该行开始 204 * @param width 图片所占的宽度 205 * @param height 图片所占的高度 206 * @param imageFile 要插入的图片文件 207 */ 208 public static void insertImage(WritableSheet sheet, 209 int col, int row, 210 int width, int height, 211 File imageFile) { 212 WritableImage img = new WritableImage(col, row, width, height, imageFile); 213 sheet.addImage(img); 214 } 215 216 217 /** 218 * @param args 219 */ 220 public static void main(String[] args) { 221 //4.测试insertImage方法 222 WritableWorkbook wwb = null; 223 try{ 224 wwb = Workbook.createWorkbook(new File("E:\\testexcel.xls")); 225 WritableSheet sheet = wwb.createSheet("image", 0); 226 File imageFile = new File("E:\\1.png"); 227 JXLOperateExcel.insertImage(sheet, 1, 4, 6, 18, imageFile); 228 wwb.write(); 229 } catch(Exception e) { 230 e.printStackTrace(); 231 } finally { 232 //如果不关闭WorkWritablebook,打开生成的Excel文件会出现”Excel格式与文件扩展名指定格式不一致“的错误。 233 if(wwb != null) { 234 try { 235 wwb.close(); 236 } catch (WriteException e) { 237 e.printStackTrace(); 238 } catch (IOException e) { 239 e.printStackTrace(); 240 } 241 } 242 } 243 244 //3.测试searchKeyWord方法 245 // File file = new File("E:\\testexcel.xls"); 246 // String keyWord = "1"; 247 // System.out.println(JXLOperateExcel.searchKeyWord(file, keyWord)); 248 249 //2.测试readExcel方法 250 // File file = new File("E:\\testexcel.xls"); 251 // System.out.println(JXLOperateExcel.readExcel(file)); 252 253 //1.测试writeExcel方法 254 // String fileName = "E:\\testexcel.xls"; 255 // JXLOperateExcel.writeExcel(fileName); 256 } 257 258 }
JXL操作Excel
4.总结
(1) 类比我们平时对Excel的操作:①找到Excel文件;②找到要操作的工作表(sheet);③找到要操作的行;④操作当前行的单元格。程序中也是这种操作顺序。
(2)WorkWritablebook一定要及时关闭。如果不关闭WorkWritablebook,打开生成的Excel文件会出现”Excel格式与文件扩展名指定格式不一致“的错误。