excel 表之间做差的java实现
0. 写在最前面
有人让我帮他们做个小程序,我觉得也不难,也还算有点意思,就揽下来了。写的比较基础,就当成学习练手过程中的一个小项目了。代码和资源发布在码云地址https://gitee.com/snowlandltd/snowland-xlsdiff/
本文欢迎转载,转载需表明出处。遵从知识共享协议。如有错误,欢迎指正。
1.问题背景
有两个excel表文件,一个文件是”分店进货验收单”(下称表1),表示用户的进货申请;一个文件是”违禁品”(下称表2),代表不能进货的物品。要求表1减去表2,得到允许进货的货物列表。
具体表结构参考 https://gitee.com/snowlandltd/snowland-xlsdiff/blob/master/res
2.问题解决思路
观察两个表的结构,发现表1,表2通过货号关联,如果用数据库操作显然很简单。但是提供的是excel表,一个简单的思路是读取excel表,使得表1的货号构成一个集合,表2的货号组成一个集合,通过集合相减得到结果表(res.xls)。
根据这个思路向下想,我们得到了货号之后,保留的应该是整行数据。所以,需要把货号所谓键(key),每行数据作为值(value),通过字典的形式把生成新的表。
3. 遇到的问题/注意事项
- 最开始的时候,我用建的java project,以为依赖的三方包只有一个poi,但是后面才发现不止,而且包和包之间有命名相同的,导致运行失败。后来改成maven project之后可以成功运行了。
- 提供的excel有xls也有xlsx,所以需要先去判断下两个excel格式。最开始的时候,我以为只有xls格式的(如果只有xls格式,那么推荐jxl,这个比poi方便的多啊~~
- HashMap可能会使得表项顺序被打乱,我使用的是LinkedHashMap,需要jdk 1.7+才支持。
4.代码
- 项目代码 https://gitee.com/snowlandltd/snowland-xlsdiff
- 在windows 7 64bit, jdk SE 1.7 运行通过
@SuppressWarnings("rawtypes")
public static void diff(Sheet s1, Sheet s2, String path) throws IOException {
Map<String, Row> map = new LinkedHashMap<>();
// System.out.println(s1.getLastRowNum());
for (Row row : s1) {
try {
// System.out.println(getCellValue(row.getCell(0)));
map.put(getCellValue(row.getCell(0)), row);
} catch (NullPointerException e) {
}
}
for (Row row : s2) {
map.remove(getCellValue(row.getCell(0)));
}
OutputStream fos = new FileOutputStream(path);
@SuppressWarnings("resource")
Workbook wb = new HSSFWorkbook();
Sheet s = wb.createSheet();
int i = 0, j = 0;
for (String key : map.keySet()) {
j = 0;
Row row = map.get(key);
Row r = s.createRow(i);
try {
for (Cell cell : row) {
Cell c = r.createCell(j);
String str = getCellValue(cell);
// System.out.println(str);
c.setCellValue(str);
++j;
}
} catch (IllegalStateException e) {
} catch (IllegalArgumentException e) {
}
++i;
}
wb.write(fos);
fos.close();
}