POI简述

JAVA语言操作excel的api主流有两种方式:
1、POI Apache它是用来操作Office所有的软件excel/word/ppt/..。而且支持所有版本。
2、JXL 它是用来操作excel 2003以下版本,2007以上版本不支持。
早期微软Office系列,当时使用OLE2文档结构;微软在开发Office2207版本时,做了一个重大的改革。重写了Office,使用OOXML文档结构。现在excel文件实际上是一个xml格式文件。
POI支持OLE2格式文件,还支持OOXML,而且在OOXML格式文件时做了很大的优化。
JXL只支持OLE2格式文件。
POI低版本有个致命弱点,当数据量超大(海量数据),性能极具降低。JXL它解决数量大时性能的问题。POI在高版本时迎头追上,加了一个补丁。OOXML支持,解决大数量时的性能问题。
http://poi.apache.org/index.html POI 全方位的操作
http://www.andykhan.com/jexcelapi/index.html JXL 导入导出
java.lang.IllegalArgumentException: Invalid column index(256).  Allowable column range for BIFF8 is(0..255) or ('A'..'IV')
java.lang.IllegalArgumentException: Invalid row number (65536)outside allowable range (0..65535)
HSSF对象支持excel 2003,excel 2003它支持行65536,支持列256
XSSF对象支持excel2007版本以上,行1048576,支持列65536。Sheet
SXSSF对象,支持excel 2007版本以上,构造函数。不支持模板方式。只能作为数据导出。
SXSSF如何实现?
HSSF/XSSF它们在构建workbook中所有对象,全部放在内存中,数据全放在内存中,wb.write时才从内存向磁盘文件中写。写完才释放内存。数据量大,堆溢出。
SXSSF构造方法Workbook wb = new SXSSFWorkbook(100);
每处理完100个对象,将它写临时文件,这部分数据所占的内存,就释放。
       File tmplFile =File.createTempFile("poi-sxssf-template", ".xlsx");
       try
       {
          FileOutputStream os = new FileOutputStream(tmplFile);
           try
           {
              _wb.write(os);
           }
          finally
           {
              os.close();
           }
          //Substitute the template entries with the generated sheet datafiles
          injectData(tmplFile, stream);
       }


在生成的xml临时文件中,只存放数据
CSV 实际文本文件,存放数据,数据之间,可以用逗号隔开,也可以用TAB隔开。通用导入导出文件。
当数据量大,跟当前电脑环境,堆溢出。
优化Myeclispse
优化jvm启动参数
a) POI入门
Excel文件
1) 创建excel文件,称作工作簿workbook
2) Excel文件在创建时,会默认创建3个工作表sheet
3) 定位行
4) 定位列,获得单元格
5) 填写内容
6) 保存,关闭
POI开发步骤:
public void HSSF() throws IOException{
//1.创建一个工作簿excel文件
Workbook wb = new HSSFWorkbook(); //HSSF操作excel 2003以下版本
//2.创建一个工作表sheet
Sheet sheet = wb.createSheet();
//3.创建一个行对象Row
Row nRow = sheet.createRow(4); //第五行,坐标从0开始
//4.创建一个单元格对象,指定列
Cell nCell = nRow.createCell(3); //第四列
//5.给单元格设置内容
nCell.setCellValue("传智播客万年长!");
//6.保存
OutputStream os = new FileOutputStream(newFile("c:\\testPOI.xls"));
wb.write(os);
//7.关闭
os.close();
}


上面代码存在的问题:
1) POI创建的这些对象统统在内存中
2) 行对象,列对象,样式对象,字体对象重复创建
15. 常规poi打印存在问题:
1) 列的宽度不精确,272非常相近
2) 设置纸张方向
3) 设置页眉页脚
4) 标题栏
5) 内容样式稍有不同,就需要创建不同的样式,写很多样式应用的语句
6) 表格头,写死表头,静态的文字方便维护
16. POI操作EXCEL,复杂报表终极解决方案~模板开发
1) 代码量急剧降低
2) POI日常API,将利用模板直接来设置,可视化修改。
3) 业务功能非常方便维护。
//模板打印
@RequestMapping("/cargo/outproduct/printTemplate.action")
public void printTemplate(String inputDate, HttpServletRequestrequest, HttpServletResponse response) throws IOException{
List dataList = outProductService.find(inputDate);
//打开模板文件
String path =request.getSession().getServletContext().getRealPath("/"); //jdk1.8bug 在linux下不带后面你写的路径
String tempFile = path +"/make/xlsprint/tOUTPRODUCT.xls";
Workbook wb = new HSSFWorkbook(new FileInputStream(newFile(tempFile)));
//写入业务内容
Sheet sheet = wb.getSheetAt(0); //获得工作表sheet
Row nRow = null;
Cell nCell = null;
int rowNo = 2;
int colNo = 1;
//获取样式
nRow = sheet.getRow(2); //获得行对象
nCell = nRow.getCell(1); //获取单元格对象
CellStyle customNameStyle = nCell.getCellStyle();//获取到样式
nCell = nRow.getCell(2);
CellStyle contractNoStyle = nCell.getCellStyle();
nCell = nRow.getCell(3);
CellStyle productNoStyle = nCell.getCellStyle();
nCell = nRow.getCell(4);
CellStyle cnumberStyle = nCell.getCellStyle();
nCell = nRow.getCell(5);
CellStyle factoryStyle = nCell.getCellStyle();
nCell = nRow.getCell(6);
CellStyle extStyle = nCell.getCellStyle();
nCell = nRow.getCell(7);
CellStyle dateStyle = nCell.getCellStyle();
nCell = nRow.getCell(9);
CellStyle tradeStyle = nCell.getCellStyle();
//大标题
nRow = sheet.getRow(0);
nCell = nRow.getCell(1);
nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-", "年") + "月份出货表"); //yyyy-MM
//处理数据
for(int j=0;j
colNo = 1; //列号初始化
OutProductVO op = dataList.get(j); //获取出货表对象
nRow = sheet.createRow(rowNo++);
nRow.setHeightInPoints(24);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getCustomName());
nCell.setCellStyle(customNameStyle); //设置样式
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getContractNo());
nCell.setCellStyle(contractNoStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getProductNo());
nCell.setCellStyle(productNoStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getCnumber());
nCell.setCellStyle(cnumberStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getFactoryName());
nCell.setCellStyle(factoryStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getExts());
nCell.setCellStyle(extStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getDeliveryPeriod());
nCell.setCellStyle(dateStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getShipTime());
nCell.setCellStyle(dateStyle);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(op.getTradeTerms());
nCell.setCellStyle(tradeStyle);
}
//下载
DownloadUtil du = new DownloadUtil();
ByteArrayOutputStream os = new ByteArrayOutputStream();
wb.write(os);
du.download(os, response, "出货表.xls");
}
public class DownloadUtil {
protected void download(String filePath,StringreturnName,HttpServletResponse response,boolean delFlag){
this.prototypeDownload(new File(filePath), returnName,response, delFlag);
}
protected void download(File file,StringreturnName,HttpServletResponse response,boolean delFlag){
this.prototypeDownload(file, returnName, response,delFlag);
}
public void prototypeDownload(File file,StringreturnName,HttpServletResponse response,boolean delFlag){
// 下载文件
FileInputStream inputStream = null;
ServletOutputStream outputStream = null;
try {
if(!file.exists()) return;
response.reset();
//设置响应类型 PDF文件为"application/pdf",WORD文件为:"application/msword",EXCEL文件为:"application/vnd.ms-excel"。  
response.setContentType("application/octet-stream;charset=utf-8");
//设置响应的文件名称,并转换成中文编码
//returnName = URLEncoder.encode(returnName,"UTF-8");
returnName = response.encodeURL(newString(returnName.getBytes(),"iso8859-1"));//保存的文件名,必须和页面编码一致,否则乱码
//attachment作为附件下载;inline客户端机器有安装匹配程序,则直接打开;注意改变配置,清除缓存,否则可能不能看到效果
response.addHeader("Content-Disposition",  "attachment;filename="+returnName);  
//将文件读入响应流
inputStream = new FileInputStream(file);
outputStream = response.getOutputStream();
int length = 1024;
int readLength=0;
byte buf[] = new byte[1024];
readLength = inputStream.read(buf, 0, length);
while (readLength != -1) {
outputStream.write(buf, 0, readLength);
readLength = inputStream.read(buf, 0, length);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
//删除原文件
if(delFlag) {
file.delete();
}
}
}
public void download(ByteArrayOutputStreambyteArrayOutputStream, HttpServletResponse response, StringreturnName) throws IOException{
response.setContentType("application/octet-stream;charset=utf-8");
returnName = response.encodeURL(newString(returnName.getBytes(),"iso8859-1"));//保存的文件名,必须和页面编码一致,否则乱码
response.addHeader("Content-Disposition",  "attachment;filename=" + returnName);  
response.setContentLength(byteArrayOutputStream.size());
ServletOutputStream outputstream = response.getOutputStream();//取得输出流
byteArrayOutputStream.writeTo(outputstream); //写到输出流
byteArrayOutputStream.close(); //关闭
outputstream.flush(); //刷数据
}
}


2) 图片如何插入到excel
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();//add picture
poiUtil.setPicture(wb, patriarch,path+"make/xlsprint/logo.jpg", 开始行, 开始列, 结束行, 结束列);
3) 如何画线
poiUtil.setLine(wb, patriarch, 开始行, 开始列, 结束行, 结束列); //drawline
4) 如何设置单元格换行
curStyle.setWrapText(true); // 换行
5) 如何设置单元格的前缀
public short rmb4Format(HSSFWorkbook wb) {
HSSFDataFormat format = wb.createDataFormat();
return format.getFormat(""¥"#,###,##0.00"); // 设置格式
}
6) 如何建立公式
nCell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
nCell.setCellFormula("F"+String.valueOf(curRow)+"*H"+String.valueOf(curRow));
7) 验货员不能由于输入审单人,它的位置不能发生变化
utilFuns.fixSpaceStr(contract.getCheckBy(),26)
8) 行自适应内容的高度
float height =poiUtil.getCellAutoHeight(printMap.get("Request"), 12f);//自动高度
9) 分页符
if(p>0){
sheet.setRowBreak(curRow++); //在第startRow行设置分页符
}
10) 数据和业务分离。单独组织数据源,打印时只关系它从哪一页获取数据?
Map pageMap = null;
ListpageList = new ArrayList(); //打印页
Map pageMap存储每页数据,打印时就无需关心数据从哪个对象中来,直接从它的pageMap拿,只需要按业务的key来获取。获取数据变的简单。打印代码和获取数据就不用交叉,代码结构更清晰,维护人更方便读程。
pageList存放所有页,每条记录就是一页,一页数据都放在pageMap中。
11) 日期格式转换,转为中文格式
UtilFuns.formatDateTimeCN(UtilFuns.dateTimeFormat(contract.getSigningDate())));
12) 合并单元格,如果有边线
操作的样式只设置了第一个单元格。手工设置其它的单元格,补上线。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值