知方号

知方号

10、借助POI实现Java生成并打印excel报表(1)

10.1、了解 Apache POI

      实际开发中,用到最多的是把数据库中数据导出生成报表,尤其是在生产管理或者财务系统中用的非常普遍。生成报表格式一般是EXCEL或者PDF 。利用Apache  POI实现数据库中数据导出生成excel报表。在java众多数据导出excel报表的第三方jar包中POI相对来说比较好用。

       

      Apache POI 是用Java编写的免费开源的跨平台 API,给Java提供对Microsoft Office格式档案读和写的功能,创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE2复合文档格式(OLE2)。借助POI,Java可以读取、创建和修改MS Excel文件、MS Word文件及MSPowerPoint文件,其中office2003、2010均可以。下面是Apache POI 中提供的几大部分的作用:

                             HSSF - 提供读写Microsoft Excel XLS格式档案的功能。

                             HSSF - 提供读写Microsoft Excel XLS格式档案的功能。

                             XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。

                             HWPF - 提供读写Microsoft Word DOC格式档案的功能。

                             HSLF - 提供读写Microsoft PowerPoint格式档案的功能。

                             HDGF - 提供读Microsoft Visio格式档案的功能。

                             HPBF - 提供读Microsoft Publisher格式档案的功能。

                             HSMF - 提供读Microsoft Outlook格式档案的功能。

创建一个excel报表步骤:                  

1. 创建新的Excel工作薄

HSSFWorkbook workbook = new HSSFWorkbook();

在Excel工作簿中建一工作表,其名为缺省值。POI中还提供了其他的一些workbook 构造方法。

2.创建一个工作表。新建一名为"工资表"的工作表:

HSSFSheet sheet = workbook.createSheet("工资表"); 

3.创建行。在索引0的位置创建行(最顶端的行):

HSSFRow row = sheet.createRow(0);

4.创建单元格。在索引0的位置创建单元格(左上端):

HSSFCell cell = row.createCell((short) 0);

            定义单元格为字符串类型(也可在创建单元格里面设置):

cell.setCellType(HSSFCell.CELL_TYPE_STRING); 

            在单元格中输入一些内容:

cell.setCellValue("增加值"); 

5.新建一输出文件流,把相应的Excel工作簿输出到本地

FileOutputStream fOut = new FileOutputStream(outputFile);

workbook.write(fOut);

fOut.flush();

             操作结束,关闭文件

fOut.close(); 

  在给单元格设置下从数据库中读取的数据。这样就可以把数据库里面的内容导入到excel了。

 

10.2、常用方法列举:

对象种类:

HSSFWorkbook excell的文档对象 

HSSFSheet excell的表单

HSSFRow excell的行

HSSFCell excell的格子单元

HSSFFont excell字体

HSSFName 名称

HSSFDataFormat 日期格式 

常用方法:

1.合并单元格

 sheet.addMergedRegion(new Region(beginRowIndex , (short) beginColumnIndex , endRowIndex , (short) endColumnIndex ));

即从A行的B列,合并到C行的D列。可以理解为一块面积。

2.设置页脚

HSSFFooter foot = sheet.getFooter();

 

foot.setLeft("左边文字:");

foot.setCenter("中间文字:");

foot.setRight(HSSFFooter.page()+"/"+HSSFFooter.numPages());//显示的为:当前页/总页数。如:1/3

3.生成Excel的思想

灵活应用java提供的数据结构(List,Map,Set)。通常习惯把每个sheet定义为一个Map元素.即:

Map.  至于数据集合,则可根据实际情况组成相应的数据结构。总之,灵活应用数据结构: 生成Excel的逻辑可扩展性相当好,而且扩展起来甚是方便,并可以在一定程序上实现Excel的动态化。

样式示例:(整数型、浮点型、布尔型、字符串型、日期格式、中西文结合式)

1 import org.apache.poi.hssf.usermodel.*; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 publicclass CreateCells 5 { 6 publicstaticvoid main(String[] args) 7 throws IOException 8 { 9 HSSFWorkbook wb = new HSSFWorkbook();//建立新HSSFWorkbook对象10 HSSFSheet sheet = wb.createSheet("new sheet");//建立新的sheet对象11 // Create a row and put some cells in it. Rows are 0 based.12 HSSFRow row = sheet.createRow((short)0);//建立新行13 // Create a cell and put a value in it.14 HSSFCell cell = row.createCell((short)0);//建立新cell15 cell.setCellValue(1);//设置cell的整数类型的值16 // Or do it on one line.17 row.createCell((short)1).setCellValue(1.2);//设置cell浮点类型的值18 row.createCell((short)2).setCellValue("test");//设置cell字符类型的值19 row.createCell((short)3).setCellValue(true);//设置cell布尔类型的值20 HSSFCellStyle cellStyle = wb.createCellStyle();//建立新的cell样式21 cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));//设置cell样式为定制的日期格式22 HSSFCell dCell =row.createCell((short)4); 23 dCell.setCellValue(new Date());//设置cell为日期类型的值24 dCell.setCellStyle(cellStyle); //设置该cell日期的显示格式25 HSSFCell csCell =row.createCell((short)5); 26 csCell.setEncoding(HSSFCell.ENCODING_UTF_16);//设置cell编码解决中文高位字节截断27 csCell.setCellValue("中文测试_Chinese Words Test");//设置中西文结合字符串28 row.createCell((short)6).setCellType(HSSFCell.CELL_TYPE_ERROR);//建立错误cell29 // Write the output to a file30 FileOutputStream fileOut = new FileOutputStream("workbook.xls"); 31 wb.write(fileOut); 32 fileOut.close(); 33 } 34 }

 

10.3、程序模块

 在表格中间插入创建行:

1 public void createNewRow(){ 2 //下移行的条件有2个:当前行非初始行,且当前行没有超过最后一行 3 if(this.currRowIndex!=this.initRowIndex && this.lastRowIndex>this.currRowIndex){ 4 //将指定的几行进行下移一行 5 sheet.shiftRows(this.currRowIndex, this.lastRowIndex, 1, true, true); 6 //既然下移了那么最后一行下标就也要增大了 7 this.lastRowIndex++; 8 } 9 //在指定的行上创建一个空行(如果此行原本有单元格和数据,那么也会被空行覆盖,且创建出来的空行是没有单元格的) 10 this.currRow = sheet.createRow(this.currRowIndex); 11 this.currRow.setHeightInPoints(this.defaultRowHeight); 12 this.currRowIndex++; 13 this.currColIndex = this.initColIndex; 14 }

单元格前(背)景色、(顶底左右)边框及颜色、位置样式设置:

1 /** 2 * 样式设置 3 */ 4 public static HSSFCellStyle createCellStyle(HSSFWorkbook workbook){ 5 // *生成一个样式 6 HSSFCellStyle style = workbook.createCellStyle(); 7 // 设置这些样式 8 // 前景色 9 style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);10 // 背景色11 style.setFillBackgroundColor(HSSFColor.GREEN.index);12 // 填充样式13 style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);14 // 设置底边框15 style.setBorderBottom(HSSFCellStyle.BORDER_THIN);16 // 设置底边框颜色17 style.setBottomBorderColor(HSSFColor.BLACK.index);18 // 设置左边框19 style.setBorderLeft(HSSFCellStyle.BORDER_THIN);20 // 设置左边框颜色21 style.setLeftBorderColor(HSSFColor.BLACK.index);22 // 设置右边框23 style.setBorderRight(HSSFCellStyle.BORDER_THIN);24 // 设置右边框颜色25 style.setRightBorderColor(HSSFColor.BLACK.index);26 // 设置顶边框27 style.setBorderTop(HSSFCellStyle.BORDER_THIN);28 // 设置顶边框颜色 29 style.setTopBorderColor(HSSFColor.BLACK.index);30 // 设置自动换行31 style.setWrapText(false);32 // 设置水平对齐的样式为居中对齐33 style.setAlignment(HSSFCellStyle.ALIGN_CENTER);34 // 设置垂直对齐的样式为居中对齐35 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);36 // HSSFFont font = createCellFont(workbook);37 // // 把字体应用到当前的样式38 // style.setFont(font);39 return style;40 }

单元格字体样式设置:

1 /** 2 * 字体设置 3 */ 4 public static HSSFFont createCellFont(HSSFWorkbook workbook){ 5 // *生成一个字体 6 HSSFFont font = workbook.createFont(); 7 // 字体颜色 8 font.setColor(HSSFColor.VIOLET.index); 9 // 字体大小10 font.setFontHeightInPoints((short) 12);11 // 字体加粗12 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);13 // 是否使用斜体14 font.setItalic( true );15 // 是否使用划线16 //font.setStrikeout(true);17 // 字体名字18 font.setFontName( " 黑体 " );19 return font;20 }

保留小数位数样式设置:

1 /**2 * 保留2位小数3 */4 HSSFCellStyle cellStyle = workbook.createCellStyle();5 Short doubleFormat = workbook.createDataFormat().getFormat("0.00");6 cellStyle.setDataFormat(doubleFormat);7 cellStyle.setDataFormat(doubleFormat);

 

注释设置:

1 /** 2 * 注释设置 3 */ 4 public static HSSFComment createCellComment(HSSFPatriarch patriarch, String commentText, String commentName){ 5 // *添加单元格注释 6 // 定义注释的大小和位置,详见文档 7 HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 1, 1, (short) 2, 2)); 8 // 设置注释内容 9 comment.setString(new HSSFRichTextString(commentText));10 // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.11 comment.setAuthor(commentName);12 return comment;13 }

图片插入设置:

1 /** 2 * 图片插入 3 */ 4 public static void createCellPicture(HSSFWorkbook workbook, HSSFPatriarch patriarch, String url, int col, int row) throws Exception{ 5 //先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray 6 BufferedImage bufferImg =null; 7 ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 8 bufferImg = ImageIO.read(new File( url )); 9 ImageIO.write(bufferImg,"jpg",byteArrayOut);10 HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0,1023, 255, (short) col, row, (short) col, row);11 anchor.setAnchorType(3);12 //插入图片13 patriarch.createPicture(anchor , workbook.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));14 byteArrayOut.flush();15 byteArrayOut.close();16 }

 

10.4、实例:

报表生成类:ComplexExportExcelClient.java

1 package com.bzu.search.action; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.apache.poi.hssf.usermodel.HSSFCell; 7 import org.apache.poi.hssf.usermodel.HSSFCellStyle; 8 import org.apache.poi.hssf.usermodel.HSSFFont; 9 import org.apache.poi.hssf.usermodel.HSSFRichTextString; 10 import org.apache.poi.hssf.usermodel.HSSFRow; 11 import org.apache.poi.hssf.usermodel.HSSFSheet; 12 import org.apache.poi.hssf.usermodel.HSSFWorkbook; 13 import org.apache.poi.hssf.util.Region; 14 15 /** 16 * 拒绝件报表生成类. 17 * 18 * @author caoyb 19 * @version $Revision:$ 20 */ 21 public class ComplexExportExcelClient { 22 23 private static HSSFWorkbook wb = new HSSFWorkbook(); 24 25 private static HSSFSheet sheet = wb.createSheet(); 26 27 @SuppressWarnings({ "unchecked", "deprecation" }) 28 public static void main(String[] args) { 29 30 ExportExcel exportExcel = new ExportExcel(wb, sheet); 31 32 // 创建列标头LIST 33 List fialList = new ArrayList(); 34 35 fialList.add("申请人未提供任何联系方式"); 36 fialList.add("无工作单位信息且未提供收入来源信息"); 37 fialList.add("有工作单位但未提供单位地址或电话"); 38 fialList.add("家庭地址缺失"); 39 fialList.add("客户身份证明资料缺"); 40 fialList.add("签名缺失或签名不符合要求"); 41 fialList.add("其它"); 42 43 List errorList = new ArrayList(); 44 45 errorList.add("客户主动取消"); 46 errorList.add("个人征信不良"); 47 errorList.add("欺诈申请"); 48 errorList.add("申请人基本条件不符"); 49 errorList.add("申请材料不合规"); 50 errorList.add("无法正常完成征信"); 51 errorList.add("重复申请"); 52 errorList.add("其他"); 53 54 // 计算该报表的列数 55 int number = 2 + fialList.size() * 2 + errorList.size() * 2; 56 57 // 给工作表列定义列宽(实际应用自己更改列数) 58 for (int i = 0; i < number; i++) { 59 sheet.setColumnWidth(i, 3000); 60 } 61 62 // 创建单元格样式 63 HSSFCellStyle cellStyle = wb.createCellStyle(); 64 65 // 指定单元格居中对齐 66 cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); 67 68 // 指定单元格垂直居中对齐 69 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); 70 71 // 指定当单元格内容显示不下时自动换行 72 cellStyle.setWrapText(true); 73 74 // 设置单元格字体 75 HSSFFont font = wb.createFont(); 76 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 77 font.setFontName("宋体"); 78 font.setFontHeight((short) 200); 79 cellStyle.setFont(font); 80 81 // 创建报表头部 82 exportExcel.createNormalHead("南京地区申请资料拒件分析统计", number); 83 84 // 设置第二行 85 String[] params = new String[] { " 年 月 日", " 年 月 日" }; 86 exportExcel.createNormalTwoRow(params, number); 87 88 // 设置列头 89 HSSFRow row2 = sheet.createRow(2); 90 91 HSSFCell cell0 = row2.createCell(0); 92 cell0.setCellStyle(cellStyle); 93 cell0.setCellValue(new HSSFRichTextString("机构代码")); 94 95 HSSFCell cell1 = row2.createCell(1); 96 cell1.setCellStyle(cellStyle); 97 cell1.setCellValue(new HSSFRichTextString("支行名称")); 98 99 HSSFCell cell2 = row2.createCell(2); 100 cell2.setCellStyle(cellStyle); 101 cell2.setCellValue(new HSSFRichTextString("无效件")); 102 103 HSSFCell cell3 = row2.createCell(2 * fialList.size() + 2); 104 cell3.setCellStyle(cellStyle); 105 cell3.setCellValue(new HSSFRichTextString("拒绝件")); 106 107 HSSFRow row3 = sheet.createRow(3); 108 109 // 设置行高 110 row3.setHeight((short) 800); 111 112 HSSFCell row3Cell = null; 113 int m = 0; 114 int n = 0; 115 116 // 创建不同的LIST的列标题 117 for (int i = 2; i < number; i = i + 2) { 118 119 if (i < 2 * fialList.size() + 2) { 120 row3Cell = row3.createCell(i); 121 row3Cell.setCellStyle(cellStyle); 122 row3Cell.setCellValue(new HSSFRichTextString(fialList.get(m) 123 .toString())); 124 m++; 125 } else { 126 row3Cell = row3.createCell(i); 127 row3Cell.setCellStyle(cellStyle); 128 row3Cell.setCellValue(new HSSFRichTextString(errorList.get(n) 129 .toString())); 130 n++; 131 } 132 133 } 134 135 // 创建最后一列的合计列 136 row3Cell = row3.createCell(number); 137 row3Cell.setCellStyle(cellStyle); 138 row3Cell.setCellValue(new HSSFRichTextString("合计")); 139 140 // 合并单元格 141 HSSFRow row4 = sheet.createRow(4); 142 143 // 合并第一列的 第三行到第五行144 sheet.addMergedRegion(new Region(2, (short) 0, 4, (short) 0)); 145 146 // 合并第二行的 第三行到第五行147 sheet.addMergedRegion(new Region(2, (short) 1, 4, (short) 1)); 148 149 // 合并第三行的 第三列到第AA指定的列 150 int aa = 2 * fialList.size() + 1; 151 sheet.addMergedRegion(new Region(2, (short) 2, 2, (short) aa)); 152 153 int start = aa + 1; 154 155 sheet.addMergedRegion(new Region(2, (short) start, 2, 156 (short) (number - 1))); 157 158 // 循环合并第四行的行,并且是每2列合并成一列 159 for (int i = 2; i < number; i = i + 2) { 160 sheet.addMergedRegion(new Region(3, (short) i, 3, (short) (i + 1))); 161 162 } 163 164 // 根据列数奇偶数的不同创建不同的列标题 165 for (int i = 2; i < number; i++) { 166 if (i < 2 * fialList.size() + 2) { 167 168 if (i % 2 == 0) { 169 HSSFCell cell = row4.createCell(i); 170 cell.setCellStyle(cellStyle); 171 cell.setCellValue(new HSSFRichTextString("无效量")); 172 } else { 173 HSSFCell cell = row4.createCell(i); 174 cell.setCellStyle(cellStyle); 175 cell.setCellValue(new HSSFRichTextString("占比")); 176 } 177 } else { 178 if (i % 2 == 0) { 179 HSSFCell cell = row4.createCell(i); 180 cell.setCellStyle(cellStyle); 181 cell.setCellValue(new HSSFRichTextString("拒绝量")); 182 } else { 183 HSSFCell cell = row4.createCell(i); 184 cell.setCellStyle(cellStyle); 185 cell.setCellValue(new HSSFRichTextString("占比")); 186 } 187 } 188 189 } 190 191 // 循环创建中间的单元格的各项的值 192 for (int i = 5; i < number; i++) { 193 HSSFRow row = sheet.createRow((short) i); 194 for (int j = 0; j

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。