1.POI主要功能
可以操作office文档的Java API
主要功能:操作excel文档
虽然也可以操作word文档,但功能比较差。Java中并没有优秀的word解析技术。
解析word建议使用.net技术。Java利用WebService技术获取解析结果。
为何要用专业组件来解析Excel?
因为Excel不是一个单纯的文本格式。
与其他excel解析技术的比较:
JXL:只能操作excel2003(现在也能操作2007-2016了)
POI:可以操作整个office(excel,doc,vb宏,ppt,visio)
2.POI支持的解析方式
HSSF解析(.xls Excel97-03版本)
-
XSSF解析(.xlsx Excel07-16版本)
解析方式不同,是由于两类版本excel文件本身的实现有不同
3.应用场景
-
导入excel数据
将excel中的备份数据还原到数据库
-
导出excel数据
将数据库中的数据导出或备份
4. 快速入门:
Maven坐标
<!--操作97-03版本用-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<!--操作07-16版本用-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
<!--?-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.11</version>
</dependency>
实现步骤:
- 创建工作簿
- 创建sheet
- 创建行对象
- 创建单元格对象
- 设置内容
- 设置内容格式
使用wb去创建内容格式,是由于创建出的字体是在工作簿内公共使用的。- 设置字体
- 设置字体大小
- 创建cellStyle
- 将cellStyle赋给cell
- 将 工作簿写入输出流
- 下载
简单Demo:
package cn.itcast.jx.poi;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class POITest {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
//1 创建工作薄:Workbook是一个接口,它有一个实现类HSSFWorkbook对象,这个对象专门操作excel97-03,excel的后缀名是xls
Workbook wb = new HSSFWorkbook();
//2 创建工作表sheet:工作表
Sheet sheet = wb.createSheet();
//3 创建行对象,java中从0开始计数
Row row = sheet.createRow(3);
//4 创建列对象
Cell cell = row.createCell(3);
//5 设置内容
cell.setCellValue("itcast,一统江湖");
//6 设置内容格式
Font font = wb.createFont();
font.setFontHeightInPoints((short)24);//以像素点的方式设置字体大小
font.setFontName("华文彩云");//设置字体
//System.out.println(Short.MIN_VALUE+"-"+Short.MAX_VALUE);
//创建格式
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setFont(font);
//将cellStyle给cell
cell.setCellStyle(cellStyle);
//7 保存(javase项目采用保存)
FileOutputStream stream = new FileOutputStream(new File("d://a.xls"));
wb.write(stream);//将对象写进流
stream.flush();
stream.close();
//8 下载(web项目 才有下载)
System.out.println("运行结束");
}
}
项目应用Demo:出货单打印:
package cn.itcast.jx.action.cargo;
import java.io.ByteArrayOutputStream;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.struts2.ServletActionContext;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
import cn.itcast.jx.action.BaseAction;
import cn.itcast.jx.domain.ContractProduct;
import cn.itcast.jx.service.ContractProductService;
import cn.itcast.jx.util.DownloadUtil;
import cn.itcast.jx.util.UtilFuns;
/**
* 打印出货表:选择时间(船期)
*/
public class OutProductAction extends BaseAction {
//获取页面提交的打印月份
private String inputDate;
public String getInputDate() {
return inputDate;
}
public void setInputDate(String inputDate) {
this.inputDate = inputDate;
}
//跳转到打印页面
public String toedit() throws Exception {
return "toedit";
}
//依赖注入
private ContractProductService contractProductService;
public void setContractProductService(
ContractProductService contractProductService) {
this.contractProductService = contractProductService;
}
//打印excel文档:
@SuppressWarnings("resource")
public String print() throws Exception {
//创建工作表
Workbook wb = new HSSFWorkbook();
//创建工作表
Sheet sheet = wb.createSheet();
//设置列宽
sheet.setColumnWidth(0, 6*256);
sheet.setColumnWidth(1, 26*256);
sheet.setColumnWidth(2, 12*256);
sheet.setColumnWidth(3, 30*256);
sheet.setColumnWidth(4, 12*256);
sheet.setColumnWidth(5, 15*256);
sheet.setColumnWidth(6, 10*256);
sheet.setColumnWidth(7, 10*256);
sheet.setColumnWidth(8, 10*256);
//定义一些公共变量
//行对象
Row nRow = null;
//单元格对象
Cell nCell = null;
//行号和列号
int rowNo = 0;
int cellNo = 1;
/************大标题的打印**************/
nRow = sheet.createRow(rowNo);
nCell = nRow.createCell(cellNo);
//横向合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,1,8));
//设置内容:
//设置内容:
/**
* 2012-01:
* 2012-10:
*
* 方式一:inputDate.replace("-0","-").replace("-","年")
* 方式二:inputDate.replace("-0","年").replace("-","年")
*
*/
nCell.setCellValue(inputDate.replace("-0","-").replace("-","年")+"月出货表");
//行高?样式?
nRow.setHeightInPoints(36f);
nCell.setCellStyle(bigTitle(wb));
/************小标题的打印**************/
//先换行
rowNo++;
//创建行对象
nRow = sheet.createRow(rowNo);
String[] titles = {"客户","订单号","货号","数量","工厂","工厂交期","船期","贸易条款"};
//遍历标题,进行输出打印
for(String title:titles){
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(title);
nCell.setCellStyle(title(wb));
}
/************内容的打印**************/
//准备数据
//String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";//mysql支持,oracle不支持
//hql中有to_char函数吗?没有,这是oracle中的pl/sql函数
//但是,hibernate强大的地方就在:你可以在HQL中使用数据库中的函数
String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm') = '"+inputDate+"'";//oracle支持
//查询:
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
//将数据放入sheet中
for(ContractProduct cp:list){
//行变化
rowNo++;
nRow = sheet.createRow(rowNo);
//列
cellNo = 1;//规1
//"客户",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getCustomName());
nCell.setCellStyle(text(wb));
//"订单号",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getContractNo());
nCell.setCellStyle(text(wb));
//"货号",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getProductNo());
nCell.setCellStyle(text(wb));
//"数量",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getCnumber());
nCell.setCellStyle(text(wb));
//"工厂",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getFactoryName());
nCell.setCellStyle(text(wb));
//"工厂交期",
nCell = nRow.createCell(cellNo++);
//用SimpleDateFormat也行
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
nCell.setCellStyle(text(wb));
//"船期",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
nCell.setCellStyle(text(wb));
//"贸易条款"
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getTradeTerms());
nCell.setCellStyle(text(wb));
}
/************下载**************/
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//将内容写入流
wb.write(byteArrayOutputStream);
//使用流
DownloadUtil downloadUtil = new DownloadUtil();
HttpServletResponse response = ServletActionContext.getResponse();
/**
* 第一个:文件流
* 第二个:response
* 第三个:下载的文件的名字
*/
downloadUtil.download(byteArrayOutputStream, response, "itcast.xls");
return NONE;
}
//大标题的样式
public CellStyle bigTitle(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short)16);
font.setBoldweight(Font.BOLDWEIGHT_BOLD); //字体加粗
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //横向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
return style;
}
//小标题的样式
public CellStyle title(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("黑体");
font.setFontHeightInPoints((short)12);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //横向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上细线
style.setBorderBottom(CellStyle.BORDER_THIN); //下细线
style.setBorderLeft(CellStyle.BORDER_THIN); //左细线
style.setBorderRight(CellStyle.BORDER_THIN); //右细线
return style;
}
//文字样式
public CellStyle text(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)10);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_LEFT); //横向居左
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上细线
style.setBorderBottom(CellStyle.BORDER_THIN); //下细线
style.setBorderLeft(CellStyle.BORDER_THIN); //左细线
style.setBorderRight(CellStyle.BORDER_THIN); //右细线
return style;
}
}
5.使用模板的实现
模板即是一个已经设置好部分样式的excel文档。
标题行,列宽行高,字体颜色等可以在模板中先设置好。
步骤
制作模板文件
-
读取模板文件,获取工作簿
//路径 String path = ServletActionContext.getRequest().getRealPath("/"); path += "/make/xlsprint/tOUTPRODUCT.xls"; //输入流 FileInputStream is = new FileInputStream(new File(path)); //借助模板创建工作簿 Workbook wb = new HSSFWorkbook(is);
-
获取sheet
Sheet sheet = wb.getSheetAt(0);
获取行
-
获取某单元格的格式
CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
设置内容及格式
将工作簿写入输出流
下载
项目应用Demo:
@SuppressWarnings("resource")
public String print() throws Exception {
//读取模板,路径
String path = ServletActionContext.getRequest().getRealPath("/");
path += "/make/xlsprint/tOUTPRODUCT.xls";//获取模板在服务器的路径
FileInputStream is = new FileInputStream(new File(path));
//1 借助模板创建工作簿
Workbook wb = new HSSFWorkbook(is);
//2 获取工作表
Sheet sheet = wb.getSheetAt(0);
//定义公共变量
Row nRow = null;//行对象
Cell nCell = null;//单元格对象
int rowNo = 0;//第几行
int cellNo = 1;//列对象
/*******************设置大标题********************/
//3 获取行对象
nRow = sheet.getRow(rowNo);
//4 获取单元格
nCell = nRow.getCell(cellNo);
// 5 设置数据
nCell.setCellValue(inputDate.replace("-0", "-").replace("-", "年")+"月份出货表");
// 6 设置样式,获取原来的样式赋值,这步可以省略
//nCell.setCellStyle(nCell.getCellStyle());
/*******************设置小标题********************/
rowNo++;//跳过小标题行,因为模板中已经设置好
/*******************设置出货数据********************/
rowNo++;//进入数据第一行行
//获取样式
nRow = sheet.getRow(rowNo);
//客户
CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
//订单号
CellStyle contractNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
//货号
CellStyle productNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
//数量
CellStyle cnumberCellStyle = nRow.getCell(cellNo++).getCellStyle();
//工厂
CellStyle factoryCellStyle = nRow.getCell(cellNo++).getCellStyle();
//工厂交期
CellStyle deliveryPeriodCellStyle = nRow.getCell(cellNo++).getCellStyle();
//船期
CellStyle shipTimeCellStyle = nRow.getCell(cellNo++).getCellStyle();
//贸易条款
CellStyle tradeTermsCellStyle = nRow.getCell(cellNo++).getCellStyle();
// 准备数据
//mysql方式(oracle不支持):
//String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";
//Oracle方式:to_char可以将Date转成varchar,oracle中的所有的PL/SQL函数都可以直接写在hql语句中
String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm')='"+inputDate+"'";
//从数据库查找要输出的货物的集合
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
for(ContractProduct cp:list){
//单元格no归1
cellNo = 1;
//一条数据创建一行
nRow = sheet.createRow(rowNo);
//创建每列的数据
//客户
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getCustomName());
nCell.setCellStyle(customerCellStyle);
//订单号
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getContractNo());
nCell.setCellStyle(contractNoCellStyle);
//货号
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getProductNo());
nCell.setCellStyle(productNoCellStyle);
//数量
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getCnumber());
nCell.setCellStyle(cnumberCellStyle);
//工厂
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getFactoryName());
nCell.setCellStyle(factoryCellStyle);
//工厂交期
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
nCell.setCellStyle(deliveryPeriodCellStyle);
//船期
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
nCell.setCellStyle(shipTimeCellStyle);
//贸易条款
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getTradeTerms());
nCell.setCellStyle(tradeTermsCellStyle);
//切到下一行,准备下一行数据操作
rowNo++;
}
/***************************************************/
// 7.写入流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//字节数组缓冲流
wb.write(byteArrayOutputStream);
// 8.下载
DownloadUtil downloadUtil = new DownloadUtil();
HttpServletResponse response = ServletActionContext.getResponse();
/**
* 第一个参数:流
* 第二个参数:response
* 第三个参数:下载的文件名
*/
downloadUtil.download(byteArrayOutputStream, response, "出货表.xls");
return NONE;
}