Android通过POI架包生成Excle表格

本文详细介绍如何使用Apache POI库在Java环境中生成Excel文件。主要内容包括POI库的简介、安装配置方法、基本概念如工作簿、工作表和单元格等,并通过一个具体案例展示了创建Excel文件的具体步骤。

前言:

在Java中打印Excel表格的有常用的类库: 1.Java Excel API项目中Jxl包。2.Apache的POI包。

本文,这里介绍Apache的POI架包。

1. POI简介:

Microsoft文档的Java API.

2. Mission Statement(使命宣言):

使命是创建和维护JavaAPI,这个API用于操作各种格式的文件,例如,Office Open XML标准(OOXML)和Microsoft的OLE2符合文档格式(OLE2)。简而言之,用使用Java读取和写入MS Excel文件,MS Word文件,MS PowerPoint文件。

OLE2文件包括大多数的Microsoft Office文件,例如XLS,DOC和PPT以及基于MFC序列化API的文件格式。POI框架提供OLE2文件系统(POIFS)和OLE2属性(HPSF)的API。

Office OpenXML格式是Microsoft Office 2007和2008找到基于标准的XML文件格式。这包括XLSX,DOCX和PPTX.POI框架提供一个低级的API来支持openxml4j的开发室包装约定。

对于每个MS Office运用程序,都存在一个组件模块,尝试为OLE2和OOXML文档格式提供高级公共的高级Java API。 Excel表格(SS=HSSF+XSSF),Word文档(WP=HWPF+XWPF),PowerPoint(SL=HSLF+XSLF).除此之外,还支持Outlook(HSMF),Visio(HDGF+XDGF) , Publisher(HPBF)。

3. Why should I use Apache POI?

Apache POI api 主要用途是用于文本提取的应用程序,例如Web spiders(蜘蛛程序),index builders(索引构建器),和 content management systems(内容管理系统)。

若是使用Java(XLS)读取或者写入Excel文件,则可以使用HSSF 。若是使用Java(XLSX)读取或者写入OOXML Excel文件,则使用XSSF 。 组合的SS接口允许使用Java轻松读取和写入Excel文件(包括XLS和XLSX)。除此之外,还有一个专门的SXSSF实现,允许以内存优化的方式编写非常大的Excel(XLSX)文件。

4. 实战案例:借助POI架包生成Excel文件

4.1 前期准备:

  1. 根据需求下载合适的版本POI架包

  2. 在androidStudio中项目添加poi-xxx.jar,然后点击右键 add as library添加引用。
    这里写图片描述

4.2 简括实现步骤:

  • 创建Workbook对象(工作簿):

    XSSFWorkbook或者HSSFWorkbook或者WorkbookFactory三种方式创建。

  • 创建Sheet对象(excle表格中的页):

    Workbook对象调用createSheet() ,被创建的Sheets将按顺序自动添加到工作簿中。Sheets默认是没有名字的,通过Workbook.setSheetName(sheetindex,”SheetName”,encoding)来设置。对于HSSF,名字是8bit格式(HSSFWorkbook.ENCODING_COMPRESSED_UNICODE)或者Unicode(HSSFWorkbook.ENCODING_UTF_16).默认的HSSF的encoding是8bit per char.对于XSSF,名字自动作为unicode处理。

  • 创建Rows对象(行):
    通过Sheets对象通过createRow(rowNumber) 来创建Rows 。Row需具备单元格值才能添加到Excel表格中。 通过setRowHeight(height)来设置行高

  • 创建Cells对象(单元格):
    通过Row对象调用 createCell(column, type)创建Cells(单元格)。只有具备值的Cell才能添加到Row中。 Cell的type必须设置为Cell.CELL_TYPE_NUMERIC 或者Cell.CELL_TYPE_STRING,取决于是否包含数字和文本值 。 Cell必须通过setCellValue()将String 或者double参数来设置值。 Cell的宽度是通过Sheet对象调用setColumnWidth(colindex, width)来设置的。

  • 设置Cell中内容和样式:
    Cells需使用CellStyle对象设置样式,这些对象又包含Font对象的引用。通过Workbook独享调用createCellStyle() 和createFont()来创建这些对象。创建按对象后,需设置参数(颜色,边框等)。通过调用setFont来为CellStyle设置字体。

  • FileOutputStream来生成Excel表格:
    调用Workbook对象调用write(outputStream),将工作簿传递给OutputStream (FileOutputStream 或者ServletOutputStream),需自己关闭OutputStream.

  • 以上各种名词的分析图如下:
    这里写图片描述
    4.3 项目实际案例:

    1. 效果图如下:

      这里写图片描述

    2. 分析和实现思路如下:

      • 创建一个工作簿,然后创建Sheet表

      • 创建第一行Row,且指定行高度。创建第一行中第一个单元格Cell,从A列到F列合并单元格,指定。

      • 创建第二行Row,指定行高度。创建第1个单元格,且将从1到3的单元格合并,文字居中。依次类推,创建第4个单元格,从4到6的单元格合并。注意点,这里的单元格角标从0开始起算。

      • 创建第三行Row,指定行高度。创建单元格,单元格内容添加换行符,实现换行效果。

      • 创建excel文件缓存路径,通过Stream生成excel表格。

      • 异步操作Stream.考虑IntentService、AsycTask、线程池、RxJava选其一。

    3. 实现代码如下:

      /**
        * 作者:新根  on 2017/3/16.
        * <p/>
         * 博客链接:http://blog.youkuaiyun.com/hexingen
         * 用途:
         *   利用Poi包,写入一个Excel表格
      */
      public class WriteExcelUtils {
      /**
       *excle表格的后缀
       */
      public static final String SUFFIX=".xls";
      public static final String DIR_FILE_NAME="EXCLE_DIR";
      
      public static final String FIRST_ROW_CONTENT="2017年3月";
      public static final  String[]  SENCOND_VALUES={"1","2"};
      public static final String[] THREE_VALUES={"一班","二班","三班"};
      public static final String[][] FOUR_VALUES={
                          {"\n涂思欢\n消元培\n黄村屏\n增东\n纳兰二狗","\n涂思欢\n消元培","\n涂思欢\n消元培"}
                           ,{"\n涂思欢\n消元培\n 哪来二狗","\n涂思欢\n消元培","\n涂思欢\n消元培"}
                        };
      
      private static Workbook createWorkbook(){
          return new HSSFWorkbook();
      }
      
      public static void writeExecleToFile(Context context){
          //创建工作簿
          Workbook workbook=createWorkbook();
          SparseArray<CellStyle> cellStyles=creatCellStyles(workbook);
          //创建execl中的一个表
          Sheet sheet= workbook.createSheet();
         // setSheet(sheet);
      
          //创建第一行
          Row headerRow=sheet.createRow(0);
          // 设置第一行:48pt的字体的内容
          headerRow.setHeightInPoints(60);
          //创建第一行中第一单元格
          Cell cell=headerRow.createCell(0);
          cell.setCellValue(FIRST_ROW_CONTENT);
          cell.setCellStyle(cellStyles.get(0));
          mergingCells(sheet,CellRangeAddress.valueOf("$A$1:$F$1"));
          //创建第二行
          Row secondRow=sheet.createRow(1);
          secondRow.setHeightInPoints(45);
          for (int i=0;i<2;++i){
              mergingCells(sheet,new CellRangeAddress(1,1,i*3,i*3+2));
              Cell cell1=secondRow.createCell(i*3);
              cell1.setCellValue(SENCOND_VALUES[i]);
              cell1.setCellStyle(cellStyles.get(1));
          }
          //创建第三行
          Row threedRow=sheet.createRow(2);
          threedRow.setHeightInPoints(40);
          for (int i=0;i<2;++i){
              for (int j=0;j<3;++j){
                  Cell cell1=threedRow.createCell(i*3+j);
                  cell1.setCellValue(THREE_VALUES[j]);
                  cell1.setCellStyle(cellStyles.get(2));
              }
          }
          //创建第四行
          Row fourRow=sheet.createRow(3);
          fourRow.setHeightInPoints(150);
          for (int i=0;i<FOUR_VALUES.length;++i){
              for (int j=0;j<FOUR_VALUES[i].length;++j){
                  Cell cell1=fourRow.createCell(i*3+j);
                  cell1.setCellValue(FOUR_VALUES[i][j]);
                  cell1.setCellStyle(cellStyles.get(3));
              }
          }
      
          writeFile(workbook,getFile(context));
      } 
         /**
       * 合并cell单元格
       *
       *  CellRangeAddress构造器中参数:
       *    参数1:first row(0-based)
       *    参数2:last row(0-based)
       *    参数3:first column(0-based)
       *    参数4:last column(0-based)
       *
       * @param sheet
       * @param cellRangeAddress
       */
      private static  void mergingCells(Sheet sheet, CellRangeAddress cellRangeAddress){
          sheet.addMergedRegion(cellRangeAddress);
      }
      
      /**
       * 设置Sheet表
       * @param sheet
       */
      private static void setSheet(Sheet sheet){
          // turn off gridlines(关闭网络线)
          sheet.setDisplayGridlines(false);
          sheet.setPrintGridlines(false);
          sheet.setFitToPage(true);
          sheet.setHorizontallyCenter(true);
      
          PrintSetup printSetup = sheet.getPrintSetup();
          printSetup.setLandscape(true);
          //只对HSSF需要用到的
          sheet.setAutobreaks(true);
          printSetup.setFitHeight((short)1);
          printSetup.setFitWidth((short)1);
      }
      
      /**
       * 获取指定文件
       * @param context
       * @return
       */
      public static  String getFile(Context context){
          File dirFile=MyUtils.getCacheFile(context,DIR_FILE_NAME);
          if(dirFile!=null&&!dirFile.exists()){
              dirFile.mkdirs();
          }
          return  dirFile.getAbsolutePath()+File.separator+new Date().getTime()+SUFFIX;
      }
      
      /**
       * 创建各种不同单元格特征,根据个人需求不同而定 。
       * @return
       */
      private static SparseArray<CellStyle> creatCellStyles(Workbook workbook){
          SparseArray<CellStyle> array=new SparseArray<>();
          //第一行的单元格特征
           CellStyle cellStyle0=createBorderedStyle(workbook);
           Font font0=creatFont(workbook);
           font0.setFontHeightInPoints((short) 14);
           font0.setBold(true);
           cellStyle0.setFont(font0);
          array.put(0,cellStyle0);
      
          //第二行的单元格特征
          CellStyle cellStyle1=createBorderedStyle(workbook);
          Font font1=creatFont(workbook);
          font1.setBold(true);
          cellStyle1.setFont(font1);
          array.put(1,cellStyle1);
          //第三行的单元格特征
          array.put(2,cellStyle1);
          //第四行的单元格特征
      
          CellStyle cellStyle3= workbook.createCellStyle();
          cellStyle3.setAlignment(HorizontalAlignment.CENTER);
          cellStyle3.setVerticalAlignment(VerticalAlignment.TOP);
          //使用换行符,需要开启wrap. 换行的文本用“\n”连接
          cellStyle3.setWrapText(true);
          array.put(3,cellStyle3);
          return    array;
      }
      /**
       * 设置表格的内容到四边的距离,表格四边的颜色
       *
       * 对齐方式:
       *   水平: setAlignment();
       *   竖直:setVerticalAlignment()
       *
       * 四边颜色:
       *    底边:  cellStyle.setBottomBorderColor()
       *
       * 四边边距:
       *
       * 填充:
       *
       * 缩进一个字符:
       *   setIndention()
       *
       * 内容类型:
       *   setDataFormat()
       * @param workbook
       * @return
       */
      private  static CellStyle createBorderedStyle(Workbook workbook){
          CellStyle cellStyle= workbook.createCellStyle();
          //对齐
          cellStyle.setAlignment(HorizontalAlignment.CENTER);
          cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
      /*     //重新设置单元格的四边颜色
          BorderStyle thin=BorderStyle.THIN;
          short blackColor_Index=IndexedColors.BLACK.getIndex();
          cellStyle.setBottomBorderColor(blackColor_Index);
          cellStyle.setBorderBottom(thin);
          cellStyle.setTopBorderColor(blackColor_Index);
          cellStyle.setBorderTop(thin);
          cellStyle.setRightBorderColor(blackColor_Index);
          cellStyle.setBorderRight(thin);
          cellStyle.setLeftBorderColor(blackColor_Index);
          cellStyle.setBorderLeft(thin);*/
          return  cellStyle;
      }
       /**
       * 创建Font
       *
       * 注意点:excle工作簿中字体最大限制为32767,应该重用字体,而不是为每个单元格都创建字体。
       *
       *  其API:
       *    setBold():设置粗体
       *    setFontHeightInPoints():设置字体的点数
       *    setColor():设置字体颜色
       *    setItalic():设置斜体
       * @param workbook
       * @return
       */
      private static Font creatFont(Workbook workbook){
          Font font=workbook.createFont();
          return font;
      }
      /**
       *  将Excle表格写入文件中
       *
       * @param workbook
       * @param fileName
       */
      private static void   writeFile(Workbook workbook ,String fileName){
          FileOutputStream outputStream=null;
          try{
              outputStream=new FileOutputStream(fileName);
              workbook.write(outputStream);
          }catch (Exception e){
              e.printStackTrace();
          }finally {
              try{
                  if(outputStream!=null){
                      outputStream.close();
                  }
                  if(workbook!=null){
                      workbook.close();
                  }
              }catch (Exception e){
                  e.printStackTrace();
              }
          }
      
      }
      
      }
    4. 附带的工具类MyUtils中代码:

         /**
       * 获得存储文件
       *
       * @param
       * @param
       * @return
       */
      public static File getCacheFile(Context context,String name) {
          String cachePath;
          if (Environment.MEDIA_MOUNTED.equals(Environment
                  .getExternalStorageState())
                  || !Environment.isExternalStorageRemovable()) {
      
              cachePath = context.getExternalCacheDir().getPath();
          } else {
              cachePath = context.getCacheDir().getPath();
          }
          return new File(cachePath + File.separator + name);
      }
    5. 根据路径生成excle表格如下:

      这里写图片描述


PIO官方资源,案例,使用指南


Busy Developers’ Guide to HSSF and XSSF Features(各种API使用介绍)

HSSF and XSSF common examples(更多官方案例参考)

  1. BusinessPlan案例是演示高级单元格格式(数字和日期格式,对齐,填充,边框)和用于在工作表(冻结窗口,分组行)中组织数据的各种设置。

  2. Calendar案例是创建多页日历,每个月都分别放在一个单独的Sheet(表)。

  3. 更多详情案例,请参考HSSF and XSSF Examples

来源参考:

android 使用poi读取高版本excel, 解决以下这两个错误 java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLEventFactory; at org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.(PackagePropertiesMarshaller.java:41) at org.apache.poi.openxml4j.opc.OPCPackage.init(OPCPackage.java:161) at org.apache.poi.openxml4j.opc.OPCPackage.(OPCPackage.java:141) at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:97) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:324) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:184) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:149) javax.xml.stream.FactoryConfigurationError: Provider com.sun.xml.internal.stream.events.XMLEventFactoryImpl not found at javax.xml.stream.FactoryFinder.newInstance(Unknown Source) at javax.xml.stream.FactoryFinder.newInstance(Unknown Source) at javax.xml.stream.FactoryFinder.find(Unknown Source) at javax.xml.stream.FactoryFinder.find(Unknown Source) at javax.xml.stream.XMLEventFactory.newInstance(Unknown Source) at org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.(PackagePropertiesMarshaller.java:41) at org.apache.poi.openxml4j.opc.OPCPackage.init(OPCPackage.java:161) at org.apache.poi.openxml4j.opc.OPCPackage.(OPCPackage.java:141) at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:97) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:324) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:184) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:149)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值