小编最近项目中遇到一个大批量Excel数据提取的问题,因为Excel数据中含有图片,所以在程序处理时遇到了困难,小编花了点时间才解决了这个问题,所以在这里mark一下。
1 问题描述
首先来描述一下数据处理的需求,如下图所以是给定Excel表的数据结构(非项目数据,自己构造),数据包括人的照片、身份证号、生日等信息,数据处理的需求是将Excel中的图片提取出来并命名为对应身份证号码保存。
2 python读取Excel内容
作为一个一个程序员首先想到的就是写一个脚本来实现自动化提取与重命名,于是想编写个python脚本来实现。大体设想就是,下载安装python读取Excel的包,读取sheet中的数据行然后将“照片”列不为空的照片保存为该行“身份证”命名的图片。
用pip安装xlrd后,用如下代码进行数据读入测试:
读取数据后的输出如下:
由python打印的输出结果分析可知,python读取Excel时将Excel的sheet分别读入一个dict中,然后通过遍历dict和dict中的内容来输出表中内容,本例中只有一个sheet中有数据。但是,python读取Excel内容只能读取Excel中的文字,对于Excel列中的图片xlrd并不能读取,如上图所示读取到的数据每一行的第一列均为空值。
3 java读取Excel中的内容及图片
python不能对所描述问题给出完美解决方案,经查阅资料小编准备转战java来实现。
首先下载并build如下Excel读取的POI的jar包:
java读取Excel中的内容和图片的代码如下:
package test;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public final class TestImportXlsx {public static void main(String[] args) throws Exception {File excelFile = new File("/root/zachary/extract_img/data.xlsx");XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(excelFile));XSSFSheet sheet = wb.getSheetAt(0);for (Row row : sheet) {for (Cell cell : row) {switch (cell.getCellType()) {case Cell.CELL_TYPE_STRING:System.out.print(cell.getRichStringCellValue().getString());System.out.print("|");break;case Cell.CELL_TYPE_NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {System.out.print(String.valueOf(cell.getDateCellValue()));} else {System.out.print(cell.getNumericCellValue());}System.out.print("|");break;case Cell.CELL_TYPE_BOOLEAN:System.out.print(cell.getBooleanCellValue());System.out.print("|");break;default:}}System.out.println();} //读取图片List<XSSFPictureData> pictures = wb.getAllPictures(); for (int i = 0; i < pictures.size(); i++) {XSSFPictureData pictureData = pictures.get(i);byte[] picData = pictureData.getData();System.out.println("image-size:" + picData.length);} System.out.println(wb.getSheetName(0));}
}
troubleshoot:
应用java能够读取到Excel中的文字与图片,那么就能利用其相关性进行图片存储并重命名。麻烦的问题是,原始数据中存在图片列为空的行,但是java的POI包只能按顺序获取到图片并已将图片为空的行自动去除,那么这样按照图片索引找的身份证ID和真正的ID会出现偏差。
为了去除图片列为空的行,需要对Excel在java读取时去掉为空的行。但是面对庞大的Excel手动去除成了一大难题,因为插入的图片是附在Excel单元格上的,所以python在读取该列时才会都读为空,java也只能按照图片在Excel中的位置顺序载入图片。经过试验,并不能通过查找空值和排序来处理掉Excel中图片列为空的行。
4 Excel图片列为空数据预处理
小编经过Excel的多方尝试,给出下面无图片行数据删除的Excel操作。
1.选中相片列---->开始---->条件格式---->突出显示单元格规则---->重复值---->选择浅红色文本填充重复值:
2.在相片列按颜色筛选内容:选中相片列--->开始---->排序和筛选--->筛选--->在相片列按照浅红色筛选内容。
3.经过筛选后只显示相片列为空的行,这样我们只需要删除了筛选出的行,然后恢复筛选前的条件即可得到删除相片列为空行的数据结果。
4 总结
综合2、3两步得到完整解决开篇描述问题的解决方案:
Excel中删除相片列为空行的数据---->java读取图片和身份证ID---->图片以ID重命名存
本篇内容在本人个人公众号上也已发布,欢迎关注本人微信公众号“勤菜鸟”。
Reference
1.http://www.cnblogs.com/lhj588/archive/2012/01/06/2314181.html
2.https://blog.csdn.net/qw0907/article/details/54617706