本文主要介绍如何使用poi读取到Excel的名称管理器中的内容。并且定位到单元格。
在企业的开发中可能需要通过名称管理器定位到某个单元格,然后在单元格上生成签名。
Java:Jdk1.8
poi:5.2.3
maven依赖(pom.xml):
org.apache.poi
poi
5.2.3
org.apache.poi
poi-ooxml
5.2.3
org.apache.poi
poi-examples
5.2.3
cn.hutool
hutool-all
5.8.15
org.slf4j
slf4j-api
1.7.36
org.apache.logging.log4j
log4j-slf4j-impl
2.9.1
org.apache.logging.log4j
log4j-api
2.17.2
org.apache.logging.log4j
log4j-core
2.17.2
com.lmax
disruptor
3.4.4
org.projectlombok
lombok
1.18.26
org.junit.jupiter
junit-jupiter-engine
5.9.3
test
poi的WorkBook有个getNames方法可以读到名称。
Excel的名称在下图中新建
以下代码用于得到单元格引用对象(CellReference)
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* POI-Excel-工具类
*
* @author namelessmyth
* @version 1.0
* @date 2023/8/4
*/
@Slf4j
public class PoiExcelUtil {
/**
* 根据名称管理器中的名称得到单元格
*
* @param book Excel工作簿对象
* @param nameName 名称的名称
* @return Cell Excel单元格对象
*/
public static Cell getNameCell(Workbook book, String nameName) {
Cell result = null;
if (book != null && StrUtil.isNotBlank(nameName)) {
Name name = book.getName(nameName);
if (name != null) {
CellReference cr = new CellReference(name.getRefersToFormula());
if (cr != null) {
result = getCell(book, cr);
}
}
} else {
throw new IllegalArgumentException("The input parameter of method can't be null");
}
return result;
}
/**
* 根据单元格引用对象得到单元格
*
* @param book Excel工作簿对象
* @param cr 单元格引用对象,例如:sheetName!$A$3
* @return Cell Excel单元格对象
*/
public static Cell getCell(Workbook book, CellReference cr) {
Cell cell = null;
if (book != null && cr != null) {
Sheet sheet = null;
if (StrUtil.isNotBlank(cr.getSheetName())) {
sheet = book.getSheet(cr.getSheetName());
}
if (sheet == null) {
throw new RuntimeException(String.format("Unable to find Sheet based on sheet name in CellReference! %s", cr.getSheetName()));
}
cell = getCell(sheet, cr);
} else {
throw new IllegalArgumentException("the input parameter of method can not be null!");
}
return cell;
}
public static Cell getCell(Sheet sheet, CellReference cr) {
Cell cell = null;
if (sheet != null && cr != null) {
Row row = sheet.getRow(cr.getRow());
if (row != null) {
cell = row.getCell(cr.getCol());
}
} else {
throw new IllegalArgumentException("the input parameter of method can not be null!");
}
return cell;
}
/**
* 返回Excel名称管理器中所有名称对应的单元格引用
*
* @param filePath Excel文件路径
* @return List
*/
public static List listNameCell(String filePath) throws IOException {
List result = null;
if (StrUtil.isNotBlank(filePath)) {
log.info("excelFilePath:{}", filePath);
Workbook book = new XSSFWorkbook(new FileInputStream(filePath));
result = listNameCell(book);
book.close();
}
return result;
}
/**
* 返回Excel名称管理器中所有名称对应的单元格引用
*
* @param book Excel工作簿对象
* @return List Excel单元格引用对象列表
*/
public static List listNameCell(Workbook book) throws IOException {
List result = null;
// 打开Excel文件
if (book != null && book.getAllNames() != null) {
result = new ArrayList<>(book.getAllNames().size());
// 获取所有的名称管理器
for (Name name : book.getAllNames()) {
String refersToFormula = name.getRefersToFormula();
if (StrUtil.isNotBlank(refersToFormula)) {
CellReference cr = new CellReference(refersToFormula);
if (cr != null) {
Cell cell = getCell(book, cr);
if (cell != null) {
result.add(cell);
}
}
}
}
}
return result;
}
/**
* 根据名称得到名称管理器中的名称单元格引用
*
* @param book Excel工作簿对象
* @param nameName 名称的名称
* @return CellReference Excel单元格引用对象
*/
public static CellReference getCellReference(Workbook book, String nameName) {
CellReference result = null;
if (book != null && StrUtil.isNotBlank(nameName)) {
Name name = book.getName(nameName);
if (name != null) {
result = new CellReference(name.getRefersToFormula());
}
}
return result;
}
} | | | |
在单元测试代码中通过CellReference来获取单元格。
CellReference中记录着sheet名字,行号,列号。
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
class PoiExcelUtilTest {
String excelPath = "E:\\resource\\方正璞华\\方正璞华\\绩效考核\\项目开发-绩效考核-20230801.xlsx";
/**
* 测试,根据excel文件和名称管理器中的名称得到单元格
* @throws IOException
*/
@Test
void getNameCell() throws IOException {
Workbook book = new XSSFWorkbook(new FileInputStream(excelPath));
Cell cell = PoiExcelUtil.getNameCell(book, "name1");
System.out.println(StrUtil.toString(cell));
}
/**
* 测试,根据excel文件和单元格引用得到单元格
* @throws IOException
*/
@Test
void getCellByReference() throws IOException {
Workbook book = new XSSFWorkbook(new FileInputStream(excelPath));
Cell cell = PoiExcelUtil.getCell(book, new CellReference("版本!$A$4"));
System.out.println(StrUtil.toString(cell));
}
/**
* 测试,读出Excel名称管理器中的所有单元格
* @throws IOException
*/
@Test
void listNameCell() throws IOException {
List cells = PoiExcelUtil.listNameCell(excelPath);
System.out.println(StrUtil.toString(cells));
}
} |