一、需求
有这样一个需求,需要将用户上传的Excel中链接的文件上传到服务器,用户会保证Excel中内容按照模板上传,第一列是省份,第二列是省份对应的上传的文件,比如下面的例子:
第二列就是链接的用户本地文件,因此服务端需要根据上传的Excel内容解析出第二列的用户本地文件的路径,然后返回给前端,前端再根据这个路径分别将用户本地的文件再上传至服务端,这里就需要解析出Excel中链接的文件的路径。
二、方案
这里主要解决解析Excel中链接的文件路径,可以使用org.apache.poi.ss.usermodel包下的类解析Excel2007版,然后根据Cell对象的getHyperlink()获取超链接对象,最后根据获取的Hyperlink对象的getAddress()方法拿到链接的文件的文件本地路径,后面就是返回给前端获取该文件上传至服务端。
三、样例
下面就以简化版的实现方式为例子,解析Excel中的链接的文件并复制到D盘目录下:
public static void main(String[] args) throws Exception {
// 需要解析的Excel文件
String fileDir = "D:\\test.xlsx";
Workbook book = null;
// 获取Excel工作簿对象
book = getExcelWorkbook(fileDir);
// 获取Excel第一个sheet
Sheet sheet = getSheetByIdx(book, 0);
// 获取sheet中有多少行数据
int lastRowNum = sheet.getLastRowNum();
System.out.println("the row count is : " + (lastRowNum + 1));
// 按行循环遍历数据
for (int i = 0; i < lastRowNum + 1; i++) {
Row row = null;
// 获取行对象
row = sheet.getRow(i);
if (row != null) {
System.out.println("row NO." + (i + 1));
// 获取一行有多少列
int lastCellNum = row.getLastCellNum();
System.out.println("the column count is : " + lastCellNum);
Cell cell = null;
// 遍历每行的列
for (int j = 0; j < lastCellNum; j++) {
System.out.println("column No." + (j + 1));
// 获取单元格对象(指定行和列的数据)
cell = row.getCell(j);
if (cell != null) {
// 单元格内容数据类型(这里没有用处)
int t = cell.getCellType();
// 获取链接的文件
Hyperlink link = cell.getHyperlink();
// 如果不为null就说明是链接文件
if (null != link) {
// 截取文件绝对路径
String fileAddr = link.getAddress().split("file:///")[1];
System.out.println("Linked file path: " + fileAddr);
// 通过字节流写入指定目录下的文件内
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File resource = new File(fileAddr);
File dest = new File("D:\\" + cell);
fis = new FileInputStream(resource);
fos = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} finally {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
}
}
}
}
}
}
}
// 获取指定sheet对象
public static Sheet getSheetByIdx(Workbook book, int idx) {
Sheet sheet = null;
try {
sheet = book.getSheetAt(idx);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return sheet;
}
// 根据文件路径获取Excel工作簿对象
public static Workbook getExcelWorkbook(String filePath) throws IOException {
Workbook book = null;
File file = null;
FileInputStream fis = null;
try {
file = new File(filePath);
if (!file.exists()) {
throw new RuntimeException("文件不存在");
} else {
fis = new FileInputStream(file);
book = WorkbookFactory.create(fis);
}
} catch (Exception e) {
throw new RuntimeException();
} finally {
if (fis != null) {
fis.close();
}
}
return book;
}
四、执行结果: