一
excel的图片不是选择嵌入单元格中的,但是在插入图片时可以设置图片格式。
依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.5</version>
<scope>compile</scope>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
读取图片
不同版本的excel有不同的拓展名(.xls .xlsx),对应不同的方法。
所有的图片在excel中保存在一个集合中,以行列号为key,图片为value,将结果封装到map集合中,图片的格式为“HSSFPictureData”“XSSFPictureData”。
package other;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
/**
* 解析Excel获取图片,并获取图片在表中的坐标
*/
public class ExcelReadImageTest {
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Administrator\\Desktop\\img-test(1).xls";
//需要解析的Excel文件
File file = new File(path);
//图片文件的下载路径
String dest = "E:\\txt\\";
int sheetIndex = 0;
ExcelReader reader = ExcelUtil.getReader(file, sheetIndex);
Workbook workbook = reader.getWorkbook();
HSSFSheet sheet = (HSSFSheet) workbook.getSheetAt(sheetIndex);
Map<String, HSSFPictureData> pictures = getPictureData(sheet);
pictures.forEach((k, v) -> {
System.out.println("k = " + k + "\t: \tv==>" + v.getMimeType());
byte[] data = v.getData();
//文件夹路径:temporarypath
File temporarypath = null;
try {
temporarypath = File.createTempFile("xxx", ".png", new File(dest));
FileOutputStream out = new FileOutputStream(temporarypath);
out.write(data);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
});
for (Row row : sheet) {
//过滤空行
if (row == null) {
continue;
}
for (Cell cell : row) {
String name = cell.getCellType().name();
switch (name) {
case "STRING":
System.out.println(cell.getRichStringCellValue().getString());
break;
case "NUMERIC":
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue());
} else {
System.out.println(cell.getNumericCellValue());
}
break;
case "BOOLEAN":
System.out.println(cell.getBooleanCellValue());
break;
case "FORMULA":
System.out.println(cell.getCellFormula());
break;
case "BLANK":
System.out.println(row.getRowNum() + "-------" + cell.getColumnIndex());
break;
default:
}
}
}
System.out.println("\n---------------------------------------------\n");
}
/**
* 获取图片和位置 (xls)
*
* @param sheet
* @return
* @throws IOException
*/
public static Map<String, HSSFPictureData> getPictureData(HSSFSheet sheet) throws IOException {
Map<String, HSSFPictureData> map = new HashMap<String, HSSFPictureData>();
List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();
for (HSSFShape shape : list) {
if (shape instanceof HSSFPicture) {
HSSFPicture picture = (HSSFPicture) shape;
HSSFClientAnchor cAnchor = picture.getClientAnchor();
HSSFPictureData pdata = picture.getPictureData();
String key = cAnchor.getRow1() + "-" + cAnchor.getCol1(); // 行号-列号
map.put(key, pdata);
}
}
return map;
}
/**
* 获取图片和位置 (xlsx)
*
* @param sheet
* @return
* @throws IOException
*/
public static Map<String, XSSFPictureData> getPictureData(XSSFSheet sheet) throws IOException {
Map<String, XSSFPictureData> map = new HashMap<String, XSSFPictureData>();
List<POIXMLDocumentPart> list = sheet.getRelations();
for (POIXMLDocumentPart part : list) {
if (part instanceof XSSFDrawing) {
XSSFDrawing drawing = (XSSFDrawing) part;
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor anchor = picture.getPreferredSize();
CTMarker marker = anchor.getFrom();
String key = marker.getRow() + "-" + marker.getCol();
map.put(key, picture.getPictureData());
}
}
}
return map;
}
}
示例
二
package util;
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.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
/**
* @author abup
* @date 2021/7/9 11:06
*/
public class ExcelUtils {
public static void main(String[] args) throws Exception {
String url="E:\\txt\\test.xls";
getExcelData(url).forEach(System.out::println);
}
/**
* 获取 Excel 文件表头信息
*
* @param fileUrl
* @return
* @throws Exception
*/
public static Set<String> getExcelHeaders(String fileUrl) throws Exception {
File file = new File(fileUrl);
InputStream is = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
System.out.println("sheet.getLastRowNum() = " + sheet.getLastRowNum());
//获取 excel 第一行数据(表头)
Row row = sheet.getRow(0);
//存放表头信息
Set<String> set = new HashSet<>();
//算下有多少列
int colCount = sheet.getRow(0).getLastCellNum();
System.out.println("colCount = " + colCount);
for (int j = 0; j < colCount; j++) {
Cell cell = row.getCell(j);
String cellValue = cell.getStringCellValue().trim();
set.add(cellValue);
}
return set;
}
/**
* 获取 Excel 文件信息(除去表头)
*
* @param fileUrl
* @return
* @throws Exception
*/
public static List<List<String>> getExcelData(String fileUrl) throws Exception {
File file = new File(fileUrl);
InputStream is = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
//获取 Excel 中 sheet 的行数
int rowNum = sheet.getLastRowNum();
System.out.println("rowNum = " + rowNum);
List<List<String>> resList = new ArrayList<>();
//负责标记检测到空行时,跳过
boolean flag = false;
for (int i = 1; i <= rowNum; i++) {
//默认认为此行为空行
flag = true;
Row row = sheet.getRow(i);
//过滤空行
if (row == null) {
continue;
}
//创建列表,负责装纳一行数据
List<String> list = new ArrayList<>();
//获取列数
int colCount = sheet.getRow(i).getLastCellNum();
for (int j = 0; j < colCount; j++) {
//获得制定空格
Cell cell = row.getCell(j);
String cellValue = "";
//如果存在空格内有内容,就将标志位设置为 false,表示这一行不是空行
if(!(cell == null)){
cellValue = getStringCellValue(cell);
if(!"".equals(cellValue)){
flag = false;
}
}
list.add(cellValue);
}
if(!flag){
resList.add(list);
}else{
continue;
}
}
return resList;
}
/**
* 获取单元格数据内容为字符串类型的数据
* @param cell Excel单元格
* @return String 单元格数据内容
*/
public static String getStringCellValue(Cell cell) {
String strCell = "";
if (cell == null) {
return "";
}
switch (cell.getCellType().name()) {
case "STRING":
strCell = cell.getStringCellValue().trim();
break;
case "NUMERIC":
strCell = String.valueOf(cell.getNumericCellValue()).trim();
break;
case "BOOLEAN":
strCell = String.valueOf(cell.getBooleanCellValue()).trim();
break;
case "BLANK":
strCell = cell.getRowIndex()+"---"+cell.getColumnIndex();
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
return strCell;
}
}
三
package util;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.ClientAnchor;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @Date 2022/5/30 10:31
* @auther by Push
*/
public class Tes {
public static void main(String[] args) throws IOException {
String[] heads = new String[]{"编号","姓名","年龄","地址","状态","照片"};
List<Employee> employees = new ArrayList<>();
Employee employee1 = new Employee(1,"张三",23,"郑州","合法");
Employee employee2 = new Employee(2,"李四",25,"合肥","合法");
Employee employee3 = new Employee(3,"王五",26,"青岛","合法");
Employee employee4 = new Employee(4,"王二麻子",27,"上海","合法");
Employee employee5 = new Employee(5,"赵子龙",28,"北京","合法");
Employee employee6 = new Employee(5,"刘能",28,"东北","合法");
employees.add(employee1);
employees.add(employee2);
employees.add(employee3);
employees.add(employee4);
employees.add(employee5);
employees.add(employee6);
List<List<String>> lists = new ArrayList<>();
employees.forEach(employee -> {
List<String> list = new ArrayList<>();
list.add(String.valueOf(employee.getId()));
list.add(employee.getUserName());
list.add(String.valueOf(employee.getUserAge()));
list.add(employee.getLocal());
list.add(employee.getRemark());
lists.add(list);
});
//先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
// String imgUrl = "https://file.qiantengcn.com/platform/fa7110f5-435c-4492-9183-8896e010a7de.png";
// URL url = new URL(imgUrl);
FileOutputStream fileOut = null;
BufferedImage bufferImg = null;
//先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
try {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("test picture");
//填充表头数据
HSSFRow row = sheet.createRow(0);
for (int i = 0; i < heads.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(heads[i]);
}
//画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
//填充实际数据
for (int i = 0; i < lists.size(); i++) {
//因为第一行表头数据已经填充过,从第二行开始填充
HSSFRow row2 = sheet.createRow(i + 1);
List<String> stringList = lists.get(i);
for (int j = 0; j < stringList.size(); j++) {
HSSFCell cell = row2.createCell(j);
cell.setCellValue(stringList.get(j));
}
//设置图片列宽度
sheet.setColumnWidth(5, 30 * 256);
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
bufferImg = ImageIO.read(new File("C:\\Users\\Administrator\\Documents\\WeChat Files\\wxid_vyx5g15g32fk22\\FileStorage\\File\\2022-05\\b2cec549f54f8c58cf3f86f351b48c5d_t.gif"));
ImageIO.write(bufferImg, "jpg", byteArrayOut);
//原始宽度
int width = bufferImg.getWidth();
//原始高度
int height = bufferImg.getHeight();
//计算该列对应高度
height = (int) Math.round((height * (30 * 13) * 1.0 / width));
row2.setHeight((short) (height / 5 * 20));
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 5, (i + 1), (short) 6, (i + 2));
anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
//插入图片
patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
}
fileOut = new FileOutputStream("D:/测试Excel.xls");
// 写入excel文件
wb.write(fileOut);
System.out.println("----Excle文件已生成------");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOut != null) {
try {
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
class Employee{
private Integer id;
private String userName;
private Integer userAge;
private String local;
private String remark;
public Employee() {
}
public Employee(Integer id, String userName, Integer userAge, String local, String remark) {
this.id = id;
this.userName = userName;
this.userAge = userAge;
this.local = local;
this.remark = remark;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", userName='" + userName + '\'' +
", userAge=" + userAge +
", local='" + local + '\'' +
", remark='" + remark + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
public String getLocal() {
return local;
}
public void setLocal(String local) {
this.local = local;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}