今天分享的是POI方法导出excel,这两个月时间我的大部分工作都是导出报表,今天就给大家分享excel报表的导出。
HSSF 提供读写旧版本Excel的功能,而XSSF提供读写新版本Excel格式档案的功能,所以在项目中我们大部分使用的XSSF的方法来导出Excel,毕竟我们没法要求客户使用的是哪个版本的office。但是新版本的兼容旧版的office,所以我建议使用XSSF方法来做Excel的导出。
POI全称为Apache POI,是Apache软件基金会的开放源码函式库,提供Java程序对Microsoft Office格式档案读和写的功能。
官方主页http://poi.apache.org/index.html,
API文档http://poi.apache.org/apidocs/index.html
MAVEN引入POI架包
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
使用代码
import com.google.common.collect.Lists;
import com.hand.hap.core.BaseConstants;
import com.hand.hap.core.IRequest;
import com.hand.hap.system.service.impl.BaseServiceImpl;
import ect.co.util.InitDataStyle;
import ect.inv.dto.InvJointBill;
import ect.inv.mapper.InvJointBillMapper;
import ect.inv.service.IInvJoinBillService;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class InvJointBillServiceImpl extends BaseServiceImpl<InvJointBill> implements IInvJoinBillService {
@Autowired
private InvJointBillMapper jointBillMapper;
/*sheet页1名称*/
private final static String SHEET1_NAME = "sheet1";
/*宽度*/
public static final int pageWidth = 12;
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(BaseConstants.DATE_FORMAT);//日期转换器
@Override
public XSSFWorkbook exportExcel(IRequest iRequest, InvJointBill invJointBill) {
InvJointBill jointBillPart=jointBillMapper.selectBill(invJointBill);
/*结算日期*/
String settlementDate="";
if(invJointBill.getSettlementDate()!=null){
settlementDate=simpleDateFormat.format(invJointBill.getSettlementDate());
}
//创建工作簿对象
XSSFWorkbook xwork = new XSSFWorkbook();
//创建工作表,这里的sheet1根据自己的实际需求更改
XSSFSheet sheet = xwork.createSheet(SHEET1_NAME);
//设置字体
XSSFFont font = xwork.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)12);
//设置下边框,并使高度居中
CellStyle rowHB = InitDataStyle.getBorderBC(xwork);
rowHB.setFont(font);
//下左右设置边框,并使高度居中
CellStyle rowHLBR = InitDataStyle.getBorderLBR(xwork);
rowHLBR.setVerticalAlignment(VerticalAlignment.CENTER);
rowHLBR.setFont(font);
//下右设置边框,并使高度居中
CellStyle rowHBR = InitDataStyle.getBorderBR(xwork);
rowHBR.setVerticalAlignment(VerticalAlignment.CENTER);
rowHBR.setFont(font);
//下设置边框,并使高度居中
CellStyle rowHLB = InitDataStyle.getBorderLB(xwork);
rowHLB.setVerticalAlignment(VerticalAlignment.CENTER);
rowHLB.setFont(font);
//下右设置边框,并使高度居中,水平居中
CellStyle rowHBCR = InitDataStyle.getBorderBCR(xwork);
rowHBCR.setVerticalAlignment(VerticalAlignment.CENTER);
rowHBCR.setFont(font);
//下设置边框,并使高度居中,水平居中
CellStyle rowHBC = InitDataStyle.getBorderBC(xwork);
rowHBC.setVerticalAlignment(VerticalAlignment.CENTER);
rowHBC.setFont(font);
//水平居中,四边设置边框,并设置自动换行
XSSFCellStyle mediumStyle = InitDataStyle.getHorizontalCenterBorder(xwork);
mediumStyle.setWrapText(true);
mediumStyle.setFont(font);
//水平居中,四周设置边框
XSSFCellStyle LeftStyle = InitDataStyle.getHorizontalCenterBorder(xwork);
LeftStyle.setFont(font);
/*标题*/
XSSFRow head = sheet.createRow(0);
XSSFCell cell = head.createCell(0);
//给单元格设置值(以下不再重复)
cell.setCellValue("结算单(协议号:" + invJointBill.getConNum() + ")");
//设置单元格样式(以下不再重复)
cell.setCellStyle(InitDataStyle.getHorizontalCenterBoldHead(xwork));
//设置单元格跨列(以下不再重复)
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, pageWidth));
/*结算日期*/
XSSFRow row2 = sheet.createRow(2);
XSSFCell cell27 = row2.createCell(7);
cell27.setCellValue("结算日期:"+settlementDate);
cell27.setCellStyle(InitDataStyle.getRight(xwork));
sheet.addMergedRegion(new CellRangeAddress(2, 2, 7, pageWidth));
/*甲方*/
XSSFRow row3 = sheet.createRow(3);
XSSFCell cell31 = row3.createCell(0);
cell31.setCellValue("甲方:"+jointBillPart.getPartNameA());
cell31.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(3, 3, 0, pageWidth-2));
/*乙方*/
XSSFRow row4 = sheet.createRow(4);
XSSFCell cell41 = row4.createCell(0);
cell41.setCellValue("乙方:"+jointBillPart.getPartNameB());
cell41.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(4, 4, 0, pageWidth-2));
/*列表*/
XSSFRow listhead = sheet.createRow(6);
List<String> colNameList = Lists.newArrayList(
"甲乙双方签订\r\n合同数量(吨)", "乙方支付甲方\r\n履约保证金(元)", "甲方退还乙方\r\n履约保证金(元)", "乙方实际\r\n交付皮棉数量(吨)",
"甲方拨付\r\n乙方资金(元)", "资金利息(元)", "甲方销售回款(元)", "乙方还款(元)", "乙方已支付\r\n管理费(元)", "冲抵乙方应付\r\n资金利息(元)",
"冲抵乙方应付\r\n代垫费用(元)", "甲方支付乙方\r\n平仓利润(元)", "甲方应支付\r\n乙方棉款(元)"
);
int num=initDate(sheet,xwork,invJointBill,7,mediumStyle);
/*备注*/
XSSFRow rowN = sheet.createRow(num);
XSSFCell cellN1 = rowN.createCell(0);
cellN1.setCellValue("备注:资金利息明细见随附资金利息结算单");
cellN1.setCellStyle(LeftStyle);
XSSFCellStyle style=InitDataStyle.getBorderBR(xwork);
for (int i=1;i<=pageWidth;i++){
XSSFCell cellNB = rowN.createCell(i);
if (i == pageWidth) {
cellNB.setCellStyle(style);
} else {
cellNB.setCellStyle(style);
}
}
sheet.addMergedRegion(new CellRangeAddress(num, num, 0, pageWidth));
/*甲方盖章*/
XSSFRow rowN1 = sheet.createRow(num+3);
XSSFCell cellN11 = rowN1.createCell(0);
cellN11.setCellValue("甲方(盖章确认):");
cellN11.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+3, num+3, 0, 1));
/*乙方盖章*/
XSSFCell cellN12 = rowN1.createCell(6);
cellN12.setCellValue("乙方(盖章确认):");
cellN12.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+3, num+3, 6, 7));
/*总经理*/
XSSFRow rowN2 = sheet.createRow(num+6);
XSSFCell cellN21 = rowN2.createCell(0);
cellN21.setCellValue("总经理:");
cellN21.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+6, num+6, 0, 1));
/*财务总监*/
XSSFRow rowN3 = sheet.createRow(num+8);
XSSFCell cellN31 = rowN3.createCell(0);
cellN31.setCellValue("财务总监:");
cellN31.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+8, num+8, 0, 1));
/*副总经理*/
XSSFRow rowN4 = sheet.createRow(num+10);
XSSFCell cellN41 = rowN4.createCell(0);
cellN41.setCellValue("副总经理:");
cellN41.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+10, num+10, 0, 1));
/*副总经理*/
XSSFRow rowN5 = sheet.createRow(num+12);
XSSFCell cellN51 = rowN5.createCell(0);
cellN51.setCellValue("棉花部负责人:");
cellN51.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+12, num+12, 0, 1));
/*副总经理*/
XSSFRow rowN6 = sheet.createRow(num+14);
XSSFCell cellN61 = rowN6.createCell(0);
cellN61.setCellValue("财务审核:");
cellN61.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+14, num+14, 0, 1));
/*副总经理*/
XSSFRow rowN7 = sheet.createRow(num+16);
XSSFCell cellN71 = rowN7.createCell(0);
cellN71.setCellValue("制表人:");
cellN71.setCellStyle(InitDataStyle.getNormal(xwork));
sheet.addMergedRegion(new CellRangeAddress(num+16, num+16, 0, 1));
for (int i = 0; i < colNameList.size(); i++) {
listhead.createCell(i).setCellValue(new XSSFRichTextString(colNameList.get(i)));
listhead.getCell(i).setCellStyle(mediumStyle);
}
//自动适应列宽
for (int i = 0; i < colNameList.size(); i++) {
sheet.autoSizeColumn(i, true);
}
return xwork;
}
/**
* 初始化数据,往报表中添加数据
* @param sheet
* @param xwork
* @param invJointBill
* @param rowNum
* @return
*/
private int initDate(XSSFSheet sheet,XSSFWorkbook xwork,InvJointBill invJointBill,int rowNum,XSSFCellStyle mediumStyle){
List<InvJointBill> invJointBillList=jointBillMapper.selectBills(invJointBill);
XSSFFont font = xwork.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)12);
for(InvJointBill jointBill:invJointBillList){
XSSFRow rowRD = sheet.createRow(rowNum);
//甲乙双方签订合同数量(吨)
XSSFCell cell1 = rowRD.createCell(0);
cell1.setCellValue(jointBill.getConQty()==null?"":jointBill.getConQty().toString());
cell1.setCellStyle(mediumStyle);
/*乙方支付甲方履约保证金(元)*/
XSSFCell cell0 = rowRD.createCell(1);
cell0.setCellValue("");
cell0.setCellStyle(mediumStyle);
/*甲方退还乙方履约保证金(元)*/
XSSFCell cell2 = rowRD.createCell(2);
cell2.setCellValue("");
cell2.setCellStyle(mediumStyle);
//乙方实际交付皮棉数量(吨)
XSSFCell cell3 = rowRD.createCell(3);
cell3.setCellValue(jointBill.getBatchWeight()==null?"":jointBill.getBatchWeight().toString());
cell3.setCellStyle(mediumStyle);
//甲方拨付乙方资金(元)
XSSFCell cell4 = rowRD.createCell(4);
BigDecimal appAmt=jointBill.getAppAmt()==null?new BigDecimal(0):jointBill.getAppAmt();
cell4.setCellValue(jointBill.getAppAmt()==null?"":jointBill.getAppAmt().toString());
cell4.setCellStyle(mediumStyle);
//资金利息(元)
XSSFCell cell5 = rowRD.createCell(5);
BigDecimal interSumAmount=jointBill.getInterestSumAmount()==null?new BigDecimal(0):jointBill.getInterestSumAmount();
cell5.setCellValue(jointBill.getInterestSumAmount()==null?"":jointBill.getInterestSumAmount().toString());
cell5.setCellStyle(mediumStyle);
//甲方销售回款(元)
XSSFCell cell6 = rowRD.createCell(6);
BigDecimal acctedAmt=jointBill.getAcctedAmt()==null?new BigDecimal(0):jointBill.getAcctedAmt();
cell6.setCellValue(jointBill.getAcctedAmt()==null?"":jointBill.getAcctedAmt().toString());
cell6.setCellStyle(mediumStyle);
//乙方还款(元)
XSSFCell cell7= rowRD.createCell(7);
cell7.setCellValue(jointBill.getNum()==null?"":jointBill.getNum().toString());
cell7.setCellStyle(mediumStyle);
//乙方已支付管理费(元)
XSSFCell cell8= rowRD.createCell(8);
BigDecimal weight=jointBill.getBatchWeight()==null?new BigDecimal(0):
jointBill.getBatchWeight().multiply(new BigDecimal(100));
cell8.setCellValue(jointBill.getBatchWeight()==null?"":
jointBill.getBatchWeight().multiply(new BigDecimal(100)).toString());
cell8.setCellStyle(mediumStyle);
//冲抵乙方应付资金利息(元)
XSSFCell cell9= rowRD.createCell(9);
cell9.setCellValue(jointBill.getBatchWeight()==null||jointBill.getPrice()==null?"":jointBill.getBatchWeight().multiply(jointBill.getPrice()).toString());
cell9.setCellStyle(mediumStyle);
//冲抵乙方应付代垫费用(元)
XSSFCell cell10= rowRD.createCell(10);
BigDecimal f8=new BigDecimal(0);
if(jointBill.getSumExp()!=null&&invJointBill.getTaxDefferrent()!=null){
f8=jointBill.getSumExp().add(invJointBill.getTaxDefferrent());
cell10.setCellValue(jointBill.getSumExp().add(invJointBill.getTaxDefferrent()).toString());
}else if(jointBill.getSumExp()==null&&invJointBill.getTaxDefferrent()!=null){
f8=invJointBill.getTaxDefferrent();
cell10.setCellValue(invJointBill.getTaxDefferrent().toString());
}else if(jointBill.getSumExp()!=null&&invJointBill.getTaxDefferrent()==null) {
f8=jointBill.getSumExp();
cell10.setCellValue(jointBill.getSumExp().toString());
}else{
cell10.setCellValue("");
}
cell10.setCellStyle(mediumStyle);
//甲方支付乙方平仓利润(元)
XSSFCell cell11= rowRD.createCell(11);
BigDecimal L8=invJointBill.getClosingProfit()==null?new BigDecimal(0):invJointBill.getClosingProfit();
cell11.setCellValue(invJointBill.getClosingProfit()==null?"":invJointBill.getClosingProfit().toString());
cell11.setCellStyle(mediumStyle);
//甲方应支付乙方棉款(元)
XSSFCell cell12= rowRD.createCell(12);
cell12.setCellValue(acctedAmt.subtract(appAmt)
.subtract(weight)
.subtract(interSumAmount)
.subtract(f8)
.add(L8).toString());
cell12.setCellStyle(mediumStyle);
rowNum++;
}
return rowNum;
}
}
XSSF样式公共类
package ect.co.util;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class InitDataStyle {
//水平居中 字体加粗
public static XSSFCellStyle getHorizontalCenterBoldHead(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getBold(wb,20);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//水平居中 字体加粗
public static XSSFCellStyle getHorizontalCenterBoldHead2(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getBold(wb,14);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//水平居中 字体加粗
public static XSSFCellStyle getHorizontalCenterBoldHead2Blue(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getBold(wb,14);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return cellStyle;
}
//水平居中
public static XSSFCellStyle getHorizontalCenter(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getNormal(wb);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//水平居中
public static XSSFCellStyle getHorizontalCenterBlue(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getNormal(wb);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return cellStyle;
}
public static XSSFCellStyle getNormal(XSSFWorkbook wb){
XSSFCellStyle cellStyle = wb.createCellStyle();
Font font=wb.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)12);
cellStyle.setFont(font);
return cellStyle;
}
//右对齐
public static XSSFCellStyle getRight(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getNormal(wb);
cellStyle.setAlignment(HorizontalAlignment.RIGHT);
return cellStyle;
}
public static XSSFCellStyle getNormalWrap(XSSFWorkbook wb){
XSSFCellStyle cellStyle = wb.createCellStyle();
Font font=wb.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)12);
cellStyle.setFont(font);
cellStyle.setWrapText(true);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return cellStyle;
}
//加粗
public static XSSFCellStyle getBold(XSSFWorkbook wb,int fontSize){
XSSFCellStyle cellStyle = wb.createCellStyle();
Font font=wb.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)fontSize);
cellStyle.setFont(font);
return cellStyle;
}
// 左上边框
public static XSSFCellStyle getBorderLT(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
return cellStyle;
}
// 右上边框
public static XSSFCellStyle getBorderTR(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
return cellStyle;
}
//上边框
public static XSSFCellStyle getBorderT(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderTop(BorderStyle.THIN);
return cellStyle;
}
//左边框
public static XSSFCellStyle getBorderL(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderLeft(BorderStyle.THIN);
return cellStyle;
}
//右边框
public static XSSFCellStyle getBorderR(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderRight(BorderStyle.THIN);
return cellStyle;
}
//左下边框
public static XSSFCellStyle getBorderLB(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
return cellStyle;
}
//下边框
public static XSSFCellStyle getBorderB(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
return cellStyle;
}
//下边框
public static XSSFCellStyle getBorderLBR(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
return cellStyle;
}
//下边框
public static XSSFCellStyle getBorderBRight(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.RIGHT);
return cellStyle;
}
//下边框,居中
public static XSSFCellStyle getBorderBC(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//右下边框
public static XSSFCellStyle getBorderBR(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
return cellStyle;
}
//右下边框,居中
public static XSSFCellStyle getBorderBCR(XSSFWorkbook wb){
XSSFCellStyle cellStyle=getNormal(wb);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//蓝色字体
public static XSSFCellStyle getBlue(XSSFWorkbook wb){
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
return cellStyle;
}
//蓝色字体
public static XSSFCellStyle getCenterBlue(XSSFWorkbook wb){
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
return cellStyle;
}
//水平居中 字体加粗加大
public static XSSFCellStyle getHorizontalCenterBoldHeadBig(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getBold(wb,16);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
return cellStyle;
}
//水平居中 四周边框
public static XSSFCellStyle getHorizontalCenterBorder(XSSFWorkbook wb){
XSSFCellStyle cellStyle = getNormal(wb);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
return cellStyle;
}
}
效果
注意事项以及感悟
不要循环创建XSSFCellStyle,因为poi对XSSFCellStyle的个数会有限定,所以相同的XSSFCellStyle在每一个类中最好只创建一个,然后让其他单元格去引用。
poi导出excel技术本身是不难的,难的是用这些技术去创造出自己需要的Excel。