前言:
在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 前期准备:
根据需求下载合适的版本POI架包
在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 项目实际案例:效果图如下:
分析和实现思路如下:
创建一个工作簿,然后创建Sheet表
创建第一行Row,且指定行高度。创建第一行中第一个单元格Cell,从A列到F列合并单元格,指定。
创建第二行Row,指定行高度。创建第1个单元格,且将从1到3的单元格合并,文字居中。依次类推,创建第4个单元格,从4到6的单元格合并。注意点,这里的单元格角标从0开始起算。
创建第三行Row,指定行高度。创建单元格,单元格内容添加换行符,实现换行效果。
创建excel文件缓存路径,通过Stream生成excel表格。
异步操作Stream.考虑IntentService、AsycTask、线程池、RxJava选其一。
实现代码如下:
/** * 作者:新根 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(); } } } }
附带的工具类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); }
根据路径生成excle表格如下:
PIO官方资源,案例,使用指南
Busy Developers’ Guide to HSSF and XSSF Features(各种API使用介绍)
- 如何创建工作簿(Workbook)
- 如何创建工作表(Sheet)
- 如何创建单元格(Cell)
- 如何创建日期单元格
- 如何创建不同类型的单元格
- 对行和单元格进行for迭代
- 获取单元格内容
- 文本提取
- 文件与Inputstreams
- 单元格中内容对齐方式
- 单元格使用四边
- 单元格填充和颜色
- 合并单元格
- 使用字体
- 自定义颜色
- 读写操作
- 单元格中内容使用换行符
- 设置单元格中内容格式
- 在一个表中设置多个footer
- 设置打印区域
- 设置页脚上页码
- 移动行
- 设置选定的工作簿
- 设置工作簿的缩放
- 创建分割和冻结窗格
- 重复行和列
- 页面和页脚
- 绘画形状
- 形状特征
- 形状和Graphics2d
- 大纲
- 图片
- 命名范围和命名单元格
- 如何设置单元格注释
- 调整列宽度适用内容
- 超链接
- 数据验证
- 嵌入对象
- 自动过滤器
- 条件格式
- 隐藏和取消隐藏行
- 设置单元格属性
- 绘图边框
- 创建数据透视表
- 设置多个特征的单元格
HSSF and XSSF common examples(更多官方案例参考)
BusinessPlan案例是演示高级单元格格式(数字和日期格式,对齐,填充,边框)和用于在工作表(冻结窗口,分组行)中组织数据的各种设置。
Calendar案例是创建多页日历,每个月都分别放在一个单独的Sheet(表)。
更多详情案例,请参考HSSF and XSSF Examples
来源参考:
Apache中POI框架:https://github.com/apache/poi
POI生成Excle表格的API使用:https://poi.apache.org/spreadsheet/quick-guide.html
Github上的POI项目:https://github.com/apache/poi
Jxl的首页:http://jxl.sourceforge.net/