# commons-office **Repository Path**: seaboot/commons-office ## Basic Information - **Project Name**: commons-office - **Description**: 基于apache-poi,功能就像Java中的Iterable,设置好读写回调之后,即可按顺序遍历Excel中任意的单元格。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-02-08 - **Last Updated**: 2025-09-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: POI ## README # commons-office #### 介绍 基于apache-poi 的 excel 内容读写工具。 1. 简化操作,提供更好的语法糖,可以很优雅地进行数据读写; 2. 提供了丰富的工具类,方便做二次封装,当然,默认的功能也能满足很多应用场景; 3. 增加 html 模版设计,可以将 html 转换成 excel。 #### 安装教程 做成 maven 依赖,或者打成 jar 包引用 #### 数据校验 导入数据的时候,可能希望有个数据校验,目前完全没有这方面的设计,也不准备升级, 因为大部分项目都会包含 hibernate-validator,可以结合一起使用即可。 #### 使用说明 常规的用法,设置好 RowReaderAndWriter 之后,即可读写任意范围的数据。 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { //使用模版的写法,使用无参的create()函数,则可以凭空创建Excel try (InputStream is = IOUtils.openFileInputStream("C:\\tpl.xlsx"); ExcelBook excelBook = ExcelBook.create(is)) { //设置工作簿号 excelBook.sheetAt(1); //起始行号 excelBook.setStartRow(0); //结束行号,如果不设置,取数时会读到最后一行 excelBook.setEndRow(100); //创建新的 Cell 时,会复制 Excel中 [0,0] 单元格样式 excelBook.cloneStyle(0, 0); //读写回调,ExcelCallback 中提供了常规对象的读写方式 excelBook.setRowReaderAndWriter(ExcelCallback.objectArrayCallback()); //读取 0-100 行的数据 List res = excelBook.read(); //从 0 行开始,写入数据 List data = new ArrayList<>(); excelBook.write(data); //之前设置的参数是可以复用的,按照前面设置好的参数,读取第二个工作表的数据 List res = excelBook.sheetAt(2).read(); } } } ``` #### 超大文件读取 超大文件读取,受限于底层实现,无法指定行号读取,只能选择页号全读 支持使用迭代器的功能,避免一次性向内容写入过多数据 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { try (InputStream is = new FileInputStream(new File("D:\\file\\excel\\test.xlsx"))) { List list = LargerExcelReader .create(is) .sheetAt(0) .setRowReaderAndWriter(ExcelCallback.objectArrayCallback()) .read(); System.out.println(list.size()); } } } ``` #### 超大文件写入 与常规读用法一模一样,只是有了切换 SXSSFWorkbook 步骤 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { try (OutputStream os = new FileOutputStream(new File("C:\\Users\\ASUS\\Desktop\\test.xlsx"))) { ExcelBook .create().asSXSSFWorkbook(1000) .setRowReaderAndWriter(ExcelCallback.objectArrayCallback()) .sheetAt(0) .setStartRow(1) .write(content) .out(os); } } } ``` #### 标题和表头样式设置 写入数据的时候,需要用到很多样式,这时候可以将样式封装到 StyleProvider, 通过 setStyle() 控制当前写入数据采用的样式。 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { try (OutputStream os = new FileOutputStream(new File("C:\\Users\\ASUS\\Desktop\\test.xlsx"))) { ExcelBook .create() .setRowReaderAndWriter(ExcelCallback.objectArrayCallback()) .sheetAt(0) .setStyleProvider(new SimpleStyleProvider()) .setStyle("title").writeTitle( 0, 2, "标题") .setStyle("header").writeArray(1, new String[]{"a", "b"}) .out(os); } } } ``` #### 添加水印 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { BufferedImage image = ImageIO.read(new File("C:\\Users\\ASUS\\Desktop\\1740022283171.png")); try (OutputStream os = new FileOutputStream(new File("C:\\Users\\ASUS\\Desktop\\test.xlsx")); ExcelBook book = ExcelBook.create()) { WatermarkTools tools = new WatermarkTools(book); tools.watermark(image, "png"); book.out(os); } } } ``` #### 添加批注 ```java public class WorkTaskExample { public static void main(String[] args) throws IOException { try (OutputStream os = new FileOutputStream(new File("C:\\Users\\ASUS\\Desktop\\test.xlsx")); ExcelBook book = ExcelBook.create()) { book.setRowReaderAndWriter(ExcelCallback.objectArrayCallback()) .sheetAt(0) .setStyleProvider(new SimpleStyleProvider()) .setStyle("title").writeTitle(0, 2, "标题") .setStyle("header").writeArray(1, new String[]{"a", "b"}); // 增加单元格批注 CommentTools tools = new CommentTools(book); tools.comment(1, 0, "adasda"); tools.comment(1, 1, "adasda"); book.out(os); } } } ``` #### html 转 excel 就是个玩具,javascript 中有丰富的代码库,不需要在后台卷。 ```java public class HtmlToExcel { public static void main(String[] args) throws IOException, DocumentException { String file = "C:\\Users\\ASUS\\Desktop\\table.xml"; try (Workbook workbook = new XSSFWorkbook()) { Sheet sheet = workbook.createSheet(); cn.seaboot.excel.sax.HtmlToExcel sax = new cn.seaboot.excel.sax.HtmlToExcel(); sax.setSheet(sheet); try (InputStream is = IOUtils.openFileInputStream(file)) { sax.parse(is); } try (OutputStream os = IOUtils.openFileOutputStream("C:\\Users\\ASUS\\Desktop\\ret.xlsx")) { workbook.write(os); } } } } ``` #### html 模版 将 html 脚本作为模版使用,html 转 excel 的过程中,替换 html 中的占位符。 基本设计,详见 test/resources/table.html: * colgroup:设置列宽 * thead:表头支持很复杂的单元格合并功能 * tfoot:同上 * tbody:根据数据循环输出列表 ```java /** * @author Mr.css * @version 2025-06-30 17:20 */ public class HtmlToExcelTpl { public static void main(String[] args) throws IOException, DocumentException { String file = "table.html"; // table-header data Map head = new HashMap<>(); head.put("title", "this is title!"); head.put("dept", "生产部门!"); // table-content data List> data = new ArrayList<>(); Map item = new HashMap<>(); int n = 9; while(n --> 0){ item.put("field0" + n, "field0" + n); item.put("field1" + n, "field1" + n); } data.add(item); data.add(item); data.add(item); data.add(item); data.add(item); // 一个设计好的表格处理器 TplTableParser parser = new TplTableParser(); parser.setHeadData(head); parser.setBodyData(data); try (Workbook workbook = new XSSFWorkbook()) { Sheet sheet = workbook.createSheet(); // 上下文,设置好需要写入的位置 ExcelContext context = new ExcelContext(); context.setSheet(sheet); parser.setContext(context); // 解析 dom 文件,并将内容映射到 excel try (InputStream is = ClassPathResource.getInputStream(file)) { SAXReader reader = new SAXReader(); Document document = reader.read(is); Element table = document.getRootElement(); parser.parse(table); } // 保存生成的 excel try (OutputStream os = IOUtils.openFileOutputStream("C:\\Users\\ASUS\\Desktop\\ret.xlsx")) { workbook.write(os); } } } } ``` #### 安装教程 最低JDK1.8 #### 参与贡献 1. Mr.css