打印出货表
* HSSFWorkbook 针对excel 2003及以前 最大行数和列数限制 最大支持65536行 都不支持百万级数据的操作
* XSSFWorkbook 针对excel 2003及以后 最大支持1048576行 都不支持百万级数据的操作
* SXSSFWorkbook 它支持百万级数据的POI 但是不支持模板打印 它不支持太多的样式
SXSSFWorkbook wb = new SXSSFWorkbook(1000);//默认值是500 使用多少行后开始清掉之前的数据 分段处理
百万级模拟
/**
* 打印出货表
* HSSFWorkbook 针对excel 2003及以前 最大行数和列数限制 最大支持65536行 都不支持百万级数据的操作
* XSSFWorkbook 针对excel 2003及以后 最大支持1048576行 都不支持百万级数据的操作
* SXSSFWorkbook 它支持百万级数据的POI 但是不支持模板打印 它不支持太多的样式
*/
@RequestMapping("/printExcel")
public void printExcel(String inputDate)throws Exception{
//1.创建Excel对象
SXSSFWorkbook wb = new SXSSFWorkbook(1000);//默认值是500 使用多少行后开始清掉之前的数据 分段处理
//2.创建Sheet对象
Sheet sheet = wb.createSheet();
//3.定义一些可复用的对象
int rowIndex = 0;//行的索引
int cellIndex = 1;//单元格的索引
Row nRow = null;
Cell nCell = null;
//4.设置列的宽度 列的宽度有bug
sheet.setColumnWidth(1,26*256);
sheet.setColumnWidth(2,12*256);
sheet.setColumnWidth(3,29*256);
sheet.setColumnWidth(4,12*256);
sheet.setColumnWidth(5,15*256);
sheet.setColumnWidth(6,10*256);
sheet.setColumnWidth(7,10*256);
sheet.setColumnWidth(8,8*256);
//5.创建大标题行 大标题:2012年8月份出货表
nRow = sheet.createRow(rowIndex++);//使用的是0,使用完了+1
//设置大标题行的高度
nRow.setHeightInPoints(36);
//6.创建大标题的单元格
nCell = nRow.createCell(cellIndex);
//7.合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,1,8));
//8.设置大标题内容
String bigTitle = inputDate.replaceAll("-0","-").replaceAll("-","年") + "月份出货表";//inputDate 2015-01 2015年1月份出货表
nCell.setCellValue(bigTitle);
//设置大标题样式
CellStyle bigTitleCellStyle = this.bigTitle(wb);
nCell.setCellStyle(bigTitleCellStyle);
//9.创建小标题内容
String[] titles = new String[]{"客户","订单号","货号","数量","工厂","工厂交期","船期","贸易条款"};
//10.创建小标题行
nRow = sheet.createRow(rowIndex++);//使用的是1,使用完了再加1
//设置小标题行高
nRow.setHeightInPoints(26.25f);
//12.创建小标题的单元格
for(String title : titles){
nCell = nRow.createCell(cellIndex++);
//设置小标题内容
nCell.setCellValue(title);
//设置小标题样式
CellStyle cellStyle = this.title(wb);
nCell.setCellStyle(cellStyle);
}
//13.获取要生成的数据
List<ContractProductVo> list = contractProductService.findContractProductByShipTime(companyId,inputDate);
//14.遍历数据
for(ContractProductVo cpv : list){
for(int i=0;i<5000;i++) { //这里遍历5000次 模拟百万级数据
//15.创建数据行
nRow = sheet.createRow(rowIndex++);
//16.设置数据行高
nRow.setHeightInPoints(24);
//17.重置cellIndex
cellIndex = 1;
//18.创建数据单元格,设置单元格内容和样式
//客户名称
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getCustomName());
//订单号
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getContractNo());
//货号
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getProductNo());
//数量
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getCnumber());
//工厂
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getFactoryName());
//工厂交期
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cpv.getDeliveryPeriod(), "yyyy-MM"));
//船期
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cpv.getShipTime(), "yyyy-MM"));
//贸易条款
nCell = nRow.createCell(cellIndex++);
nCell.setCellValue(cpv.getTradeTerms());
}
}
//the last:下载出货表文件
ByteArrayOutputStream bos = new ByteArrayOutputStream();//字节数组的输出流,它可存可取,带缓冲区
wb.write(bos);
new DownloadUtil().download(bos,response,bigTitle+"出货表.xlsx");
bos.close();
wb.close();
}
百万级数据 上传
ExcelParse 此次代码都一样
public class ExcelParse {
public void parse (String path) throws Exception {
//解析器
SheetHandler hl = new SheetHandler();
//1.根据 Excel 获取 OPCPackage 对象
OPCPackage pkg = OPCPackage.open(path, PackageAccess.READ);
try {
//2.创建 XSSFReader 对象
XSSFReader reader = new XSSFReader(pkg);
//3.获取 SharedStringsTable 对象
SharedStringsTable sst = reader.getSharedStringsTable();
//4.获取 StylesTable 对象
StylesTable styles = reader.getStylesTable();
XMLReader parser = XMLReaderFactory.createXMLReader();
// 处理公共属性
parser.setContentHandler(new XSSFSheetXMLHandler(styles,sst, hl,
false));
XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator)
reader.getSheetsData();
//逐行读取逐行解析
while (sheets.hasNext()) {
InputStream sheetstream = sheets.next();
InputSource sheetSource = new InputSource(sheetstream);
try {
parser.parse(sheetSource);
} finally {
sheetstream.close();
}
}
} finally {
pkg.close();
}
}
public static void main(String[] args)throws Exception {
new ExcelParse().parse("C:\\Users\\zhy\\Desktop\\测试.xlsx");
}
}
这次代码 获取到Excel后要干什么
package com.itheima.poi.handler;
import com.itheima.domain.ContractProductVo;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* 这个类是谁用谁写。
* 它是针对读取完excel的内容之后要做什么事
*
* 读取excel的两种思想:
* 第一种:全部读取
* 它的优势:对excel的增删改查都方便
* 它的弊端:由于要加载完整合excel文件,如果文件过大时,对内存消耗严重
* 第二种:按事件触发
* 触发到什么事件,就读什么内容。
* 事件分为:
* 读到行的开始
* 读到行的结束
* 读到一行的内容
*
* 它的优势:执行解析效率高,因为它是按照事件触发的。一次只读一行数据
* 它的弊端:不利于保存,更新和删除。因为它没有读完整个excel,所以对整个excel的结构不清楚。
* 它适用于数据量级比较大的情况
* -----------------------------------------------------------------------------------------
* XML的解析:
* dom4j:
* 它的特征:加载完整xml文档。
* 优势:增删改查都方便
* 弊端:文档不要太大,太大的话消耗内存严重
*
* sax解析:
* 它的特征:按照事件解析XML
* 事件分为:
* 文档的开始
* 文档的结束
* 标签的开始
* 标签的结束
* 标签的内容
* 它的优势和弊端域poi的百万级数据解析是一样的
*
* @author 黑马程序员
* @Company http://www.itheima.com
*/
public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
/**
* 每一行创建一个 vo对象
* 当此行解析结束之后,打印vo对象
*/
private ContractProductVo vo;
//开始解析某一行
//int : 行号
public void startRow(int i) {
//实例化vo对象
if (i >= 2) {
vo = new ContractProductVo();
}
}
//此行解析结束
public void endRow(int i) {
System.out.println(vo);
//业务逻辑
}
//获取当前行,每一个单元个的数据
/**
* @param cellName : 当前单元格名称
* B32 C23 DXX
* @param cellValue : 当前单元格数据
* @param xssfComment : 注释
* <p>
* 客户 C3 货号 数量 工厂 工厂交期 船期 贸易条款
*/
public void cell(String cellName, String cellValue, XSSFComment xssfComment) {
String name = cellName.substring(0, 1);//B2--->B F2---->F
if (vo != null) {
switch (name) {
case "B": {
vo.setCustomName(cellValue);
break;
}
case "C": {
vo.setContractNo(cellValue);
break;
}
case "D": {
vo.setProductNo(cellValue);
break;
}
case "E": {
vo.setCnumber(Integer.parseInt(cellValue));
break;
}
case "F": {
vo.setFactoryName(cellValue);
break;
}
case "G": {
try {
vo.setDeliveryPeriod(new SimpleDateFormat("yyyy-MM-dd").parse(cellValue));
} catch (ParseException e) {
e.printStackTrace();
}
break;
}
case "H": {
try {
vo.setShipTime(new SimpleDateFormat("yyyy-MM-dd").parse(cellValue));
} catch (ParseException e) {
e.printStackTrace();
}
break;
}
case "I": {
vo.setTradeTerms(cellValue);
break;
}
default: {
break;
}
}
}
}
}