使用Apache POI生成和读取Excel表数据
Apache POI是Apache软件基金会的开源项目,提供了Java操作Microsoft Office格式文件的API。本文将介绍如何使用Apache POI生成和读取Excel表数据。
一、导入Maven依赖
在项目的pom.xml文件中添加Apache POI相关依赖:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.16</version> </dependency>
|
说明:
poi:处理.xls格式的Excel文件
poi-ooxml:处理.xlsx格式的Excel文件
二、入门案例
2.1 生成Excel文件并写入数据
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileOutputStream;
public class POITest {
public static void write() throws Exception { XSSFWorkbook excel = new XSSFWorkbook(); XSSFSheet sheet = excel.createSheet("info"); XSSFRow row = sheet.createRow(1); row.createCell(1).setCellValue("姓名"); row.createCell(2).setCellValue("城市");
row = sheet.createRow(2); row.createCell(1).setCellValue("张三"); row.createCell(2).setCellValue("北京");
row = sheet.createRow(3); row.createCell(1).setCellValue("李四"); row.createCell(2).setCellValue("南京");
FileOutputStream out = new FileOutputStream(new File("F:\\CangQiongWaiMai\\Demo\\ExcelTest\\info.xlsx")); excel.write(out);
out.close(); excel.close(); }
|
2.2 读取Excel文件中的内容
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileInputStream; import java.io.InputStream;
public class POITest {
public static void read() throws Exception { InputStream in = new FileInputStream(new File("F:\\CangQiongWaiMai\\Demo\\ExcelTest\\info.xlsx"));
XSSFWorkbook excel = new XSSFWorkbook(in); XSSFSheet sheet = excel.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
for (int i = 1; i < lastRowNum; i++) { XSSFRow row = sheet.getRow(i); String cellValue1 = row.getCell(1).getStringCellValue(); String cellValue2 = row.getCell(2).getStringCellValue(); System.out.println(cellValue1 + " " + cellValue2); }
in.close(); excel.close(); }
public static void main(String[] args) throws Exception { write(); read(); } }
|
三、实际案例 - 导出运营数据报表
3.1 Controller层实现
import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse;
@RestController public class ReportController {
@Autowired private ReportService reportService;
@GetMapping("/export") @ApiOperation("导出运营数据报表") public void export(HttpServletResponse response) { reportService.exportBusinessData(response); } }
|
3.2 Service层接口
import javax.servlet.http.HttpServletResponse;
public interface ReportService {
void exportBusinessData(HttpServletResponse response); }
|
3.3 Service层实现
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime;
@Service public class ReportServiceImpl implements ReportService {
@Autowired private WorkspaceService workspaceService;
@Override public void exportBusinessData(HttpServletResponse response) { LocalDate dateBegin = LocalDate.now().minusDays(30); LocalDate dateEnd = LocalDate.now().minusDays(1);
BusinessDataVO businessDataVO = workspaceService.getBusinessData( LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX) );
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
try { XSSFWorkbook excel = new XSSFWorkbook(in);
XSSFSheet sheet = excel.getSheet("Sheet1");
sheet.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd);
XSSFRow row = sheet.getRow(3); row.getCell(2).setCellValue(businessDataVO.getTurnover()); row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate()); row.getCell(6).setCellValue(businessDataVO.getNewUsers());
row = sheet.getRow(4); row.getCell(2).setCellValue(businessDataVO.getValidOrderCount()); row.getCell(3).setCellValue(businessDataVO.getUnitPrice());
for (int i = 0; i < 30; i++) { LocalDate date = dateBegin.plusDays(i); BusinessDataVO businessData = workspaceService.getBusinessData( LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX) );
row = sheet.getRow(7 + i); row.getCell(1).setCellValue(date.toString()); row.getCell(2).setCellValue(businessData.getTurnover()); row.getCell(3).setCellValue(businessData.getValidOrderCount()); row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); row.getCell(5).setCellValue(businessData.getUnitPrice()); row.getCell(6).setCellValue(businessData.getNewUsers()); }
ServletOutputStream out = response.getOutputStream(); excel.write(out);
out.close(); excel.close();
} catch (IOException e) { e.printStackTrace(); } } }
|
四、Apache POI主要类说明
| 类名 |
描述 |
备注 |
| XSSFWorkbook |
Excel工作簿 |
对应.xlsx文件 |
| HSSFWorkbook |
Excel工作簿 |
对应.xls文件(较早版本) |
| XSSFSheet |
Excel工作表 |
工作簿中的一个Sheet页 |
| XSSFRow |
Excel行 |
工作表中的一行 |
| XSSFCell |
Excel单元格 |
行中的一个单元格 |
| XSSFCellStyle |
单元格样式 |
设置单元格格式、对齐等 |
| XSSFFont |
字体设置 |
设置单元格中字体属性 |
五、注意事项
文件格式区分:
.xlsx格式文件使用XSSF相关类
.xls格式文件使用HSSF相关类
资源关闭:
- 使用完毕后需要关闭
Workbook、FileInputStream、FileOutputStream等资源
- 建议使用try-with-resources语法自动关闭资源
大文件处理:
- 处理大量数据时,考虑使用SXSSF(流式XSSF)来减少内存占用
- 设置适当的内存策略和临时文件位置
单元格类型:
- 在读取单元格时,需要注意单元格的数据类型(字符串、数值、日期等)
- 使用对应的方法获取值,如
getStringCellValue()、getNumericCellValue()等
模板使用:
- 使用预设模板可以提高开发效率,保持报表格式一致性
- 模板文件通常放在resources目录下
通过以上代码示例和说明,可以快速上手使用Apache POI进行Excel文件的生成和读取操作。