转载自:https://www.cnblogs.com/gdwkong/p/8669220.html
一、POI概述
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
结构:
-
- HSSF - 提供读写Microsoft Excel格式档案的功能。
- XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
- HWPF - 提供读写Microsoft Word格式档案的功能。
- HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
- HDGF - 提供读写Microsoft Visio格式档案的功能。
使用必须引入依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
注:3.17版本是支持jdk6的最后版本
二、HSSF概况
HSSF 是Horrible SpreadSheet Format的缩写,通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。
三、 POI EXCEL文档结构类
- HSSFWorkbook excel文档对象
- HSSFSheet excel的sheet
- HSSFRow excel的行
- HSSFCell excel的单元格
- HSSFFont excel字体
- HSSFName 名称
- HSSFDataFormat 日期格式
- HSSFHeader sheet头
- HSSFFooter sheet尾
- HSSFCellStyle cell样式
- HSSFDateUtil 日期
- HSSFPrintSetup 打印
- HSSFErrorConstants 错误信息表
四、EXCEL的读写操作
1、读取“区域数据.xls”并储存于list集合中,“区域数据.xls”如下图
public List<Area> importXLS(){
ArrayList<Area> list = new ArrayList<>();
try {
//1、获取文件输入流
InputStream inputStream = new FileInputStream("/Users/Shared/区域数据.xls");
//2、获取Excel工作簿对象
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
//3、得到Excel工作表对象
HSSFSheet sheetAt = workbook.getSheetAt(0);
//4、循环读取表格数据
for (Row row : sheetAt) {
//首行(即表头)不读取
if (row.getRowNum() == 0) {
continue;
}
//读取当前行中单元格数据,索引从0开始
String areaNum = row.getCell(0).getStringCellValue();
String province = row.getCell(1).getStringCellValue();
String city = row.getCell(2).getStringCellValue();
String district = row.getCell(3).getStringCellValue();
String postcode = row.getCell(4).getStringCellValue();
Area area = new Area();
area.setCity(city);
area.setDistrict(district);
area.setProvince(province);
area.setPostCode(postcode);
list.add(area);
}
//5、关闭流
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
2、导出数据到“区域数据.xls”文件中,页面数据如下图:
public void exportExcel() throws IOException {
Page<Area> page = areaService.pageQuery(null);
List<Area> list = page.getContent();
//1.在内存中创建一个excel文件
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
//2.创建工作簿
HSSFSheet sheet = hssfWorkbook.createSheet();
//3.创建标题行
HSSFRow titlerRow = sheet.createRow(0);
titlerRow.createCell(0).setCellValue("省");
titlerRow.createCell(1).setCellValue("市");
titlerRow.createCell(2).setCellValue("区");
titlerRow.createCell(3).setCellValue("邮编");
titlerRow.createCell(4).setCellValue("简码");
titlerRow.createCell(5).setCellValue("城市编码");
//4.遍历数据,创建数据行
for (Area area : list) {
//获取最后一行的行号
int lastRowNum = sheet.getLastRowNum();
HSSFRow dataRow = sheet.createRow(lastRowNum + 1);
dataRow.createCell(0).setCellValue(area.getProvince());
dataRow.createCell(1).setCellValue(area.getCity());
dataRow.createCell(2).setCellValue(area.getDistrict());
dataRow.createCell(3).setCellValue(area.getPostcode());
dataRow.createCell(4).setCellValue(area.getShortcode());
dataRow.createCell(5).setCellValue(area.getCitycode());
}
//5.创建文件名
String fileName = "区域数据统计.xls";
//6.获取输出流对象
HttpServletResponse response = ServletActionContext.getResponse();
ServletOutputStream outputStream = response.getOutputStream();
//7.获取mimeType
ServletContext servletContext = ServletActionContext.getServletContext();
String mimeType = servletContext.getMimeType(fileName);
//8.获取浏览器信息,对文件名进行重新编码
HttpServletRequest request = ServletActionContext.getRequest();
fileName = FileUtils.filenameEncoding(fileName, request);
//9.设置信息头
response.setContentType(mimeType);
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//10.写出文件,关闭流
hssfWorkbook.write(outputStream);
hssfWorkbook.close();
}
工具类
public class FileUtils {
public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
String agent = request.getHeader("User-Agent"); //获取浏览器
if (agent.contains("Firefox")) {
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";
} else if(agent.contains("MSIE")) {
filename = URLEncoder.encode(filename, "utf-8");
} else if(agent.contains ("Safari")) {
filename = new String (filename.getBytes ("utf-8"),"ISO8859-1");
} else {
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
写出xls文件:
五、 EXCEL常用操作方法
1、 得到Excel常用对象
POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));
//得到Excel工作簿对象
HSSFWorkbook wb = new HSSFWorkbook(fs);
//得到Excel工作表对象
HSSFSheet sheet = wb.getSheetAt(0);
//得到Excel工作表的行
HSSFRow row = sheet.getRow(i);
//得到Excel工作表指定行的单元格
HSSFCell cell = row.getCell((short) j);
cellStyle = cell.getCellStyle();//得到单元格样式
2、建立Excel常用对象
HSSFWorkbook wb = new HSSFWorkbook();//创建Excel工作簿对象
HSSFSheet sheet = wb.createSheet("new sheet");//创建Excel工作表对象
HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行
cellStyle = wb.createCellStyle();//创建单元格样式
row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格
row.createCell((short)0).setCellValue(1); //设置Excel工作表的值
3、设置sheet名称和单元格内容
1 wb.setSheetName(1, "第一张工作表",HSSFCell.ENCODING_UTF_16);
2 cell.setEncoding((short) 1);
3 cell.setCellValue("单元格内容");
4、取得sheet的数目
1 wb.getNumberOfSheets()
5、 根据index取得sheet对象
1 HSSFSheet sheet = wb.getSheetAt(0);
6、取得有效的行数
1 int rowcount = sheet.getLastRowNum();
7、取得一行的有效单元格个数
1 row.getLastCellNum();
8、单元格值类型读写
1 cell.setCellType(HSSFCell.CELL_TYPE_STRING); //设置单元格为STRING类型
2 cell.getNumericCellValue();//读取为数值类型的单元格内容
9、设置列宽、行高
1 sheet.setColumnWidth((short)column,(short)width);
2 row.setHeight((short)height);
10、添加区域,合并单元格
1 Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo
2 ,(short)columnTo);//合并从第rowFrom行columnFrom列
3 sheet.addMergedRegion(region);// 到rowTo行columnTo的区域
4 //得到所有区域
5 sheet.getNumMergedRegions()
11、保存Excel文件
1 FileOutputStream fileOut = new FileOutputStream(path);
2 wb.write(fileOut);
12、根据单元格不同属性返回字符串数值
public String getCellStringValue(HSSFCell cell) {
String cellValue = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING://字符串类型
cellValue = cell.getStringCellValue();
if(cellValue.trim().equals("")||cellValue.trim().length()<=0)
cellValue=" ";
break;
case HSSFCell.CELL_TYPE_NUMERIC: //数值类型
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA: //公式
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
cellValue=" ";
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
break;
case HSSFCell.CELL_TYPE_ERROR:
break;
default:
break;
}
return cellValue;
}
13、常用单元格边框格式
1 HSSFCellStyle style = wb.createCellStyle();
2 style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框
3 style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框
4 style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
5 style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
14、设置字体和内容位置
HSSFFont f = wb.createFont();
f.setFontHeightInPoints((short) 11);//字号
f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗
style.setFont(f);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
style.setRotation(short rotation);//单元格内容的旋转的角度
HSSFDataFormat df = wb.createDataFormat();
style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式
cell.setCellFormula(string);//给单元格设公式
style.setRotation(short rotation);//单元格内容的旋转的角度
15、插入图片
//先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageIO.read(new File("ok.jpg"));
ImageIO.write(bufferImg,"jpg",byteArrayOut);
//读进一个excel模版
FileInputStream fos = new FileInputStream(filePathName+"/stencil.xlt");
fs = new POIFSFileSystem(fos);
//创建一个工作薄
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);
patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));
16、调整工作表位置
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFPrintSetup ps = sheet.getPrintSetup();
sheet.setAutobreaks(true);
ps.setFitHeight((short)1);
ps.setFitWidth((short)1);