导出报表 ireport 与 poi

本文介绍了为何从ireport转向使用Apache POI操作Excel的原因,包括ireport在导出Excel时遇到的背景透明、斜线显示和单元格合并等问题。接着详细阐述了POI的基本概念,如HSSF、EXCEL文档结构类以及常用操作方法,如创建、读取和设置单元格内容、合并单元格等。POI提供的灵活性和功能强大性使其成为处理复杂Excel表格的首选工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

</pre>导出报表 ireport 与 poi <p></p><p></p><p>项目需要,制作各种表格,尝试了这两种报表工具,ireport 与poi 都能完成你想要的表格,功能都很强大。</p><p></p><p>1. 配置</p><p>     ireport  必须安装ireport 客户端,具体可以参考网上资源。而poi 没有这个步骤。当然都需要在intellij (或eclipse)上导包,pom.xml 中配置,版本号对应下载的包是同一给版本。</p><p></p><p>2. 写查询语句</p><p>ireport 即在其客户端写查询语句,并按照需求编排字段,这个步骤比较花时间,一点点不对齐都会导致导出的excel 表格行列不一致,工具上可以预览导出表格的样式,也可以直接在工具上导出报表,这也是这个工具最大的用处吧,只要会sql语句,就可以制作各种表格,对其他非java编程工作人员导出报表很实用。具体操作可以参考相关教程。完成表格制作后将编译好的两个文件(.jasper,.jrxml)复制放到 intellij 资源路径下。</p><p></p><p>ireport  需要在mapper 中写查询语句,这个其实在页面端需求时已经写好,直接调用即可。</p><p></p><p>3. 后台程序编写</p><p> ireport 后台程序比较简单,将ireport 导出报表需要的参数 组装好传进去即可,直接上例子:</p><p></p><pre code_snippet_id="1579867" snippet_file_name="blog_20160216_2_5403460" name="code" class="java"> public Object exportDetailExcelByIreport(HttpServletRequest request, HttpServletResponse response, String date, String cid) {
	        String exportFileName = "districtDetailCount"+System.currentTimeMillis()+".xls";
	        String jasperFilePath = this.getClass().getResource("/").getPath()+"/"+"ireport/reportDistrict.jasper";
	        Map<String, Object> params = new HashMap<>();
	        List<!-- <Map> --> selectDistrictData = countDistrictService.searchDistrictDetail(date,cid);
	        List<!-- <Map> --> districtDetail = countDistrictService.searchDistrictNameById(Integer.parseInt(cid));
	
	        double totalNet = 0;
	        for (int i=0;i<selectDistrictData.size();i++){
	            totalNet += Double.parseDouble(selectDistrictData.get(i).get("net").toString());
	        }
	        params.put("date_month","2015-07");
	        params.put("net_total", totalNet);
	        params.put("district_name","桂城街道");
	        Map result = IReportUtils.exportByDataBaseConnection(request,response,params,exportFileName,jasperFilePath);
	        return sendResult(ResultCode.CODE_200.code,ResultCode.CODE_200.msg,result);
	    }

poi 后台程序 逻辑很清晰,从数据库取数据一行行将数据存储到excel表格的行中,代码如下:

 public Object exportDetailExcel(HttpServletRequest request, String date, String cid) {
        Map<String, Object> result = new HashMap<>();
        String path = PathKit.getWebRootPath()+"/upload/file/";
        File pathFile = new File(path);
        String districtNameList = countDistrictService.searchDistrictNameById(Integer.parseInt(cid));
        String title = districtNameList+"收运量统计表"+System.currentTimeMillis();
        List<Map> districtData = countDistrictService.searchDistrictDetail(date,cid);

        File newFile = new File(path+title+".xls");
        try{
            if(!pathFile.exists()){
                pathFile.mkdirs();
            }
            newFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try{
            FileOutputStream fos = new FileOutputStream(newFile);
            if (!districtData.isEmpty()&&districtData.size()>0){
                String[] headers = getDistrictHeaders();
                String[] titleHead = getDistrictTitle(date,cid);
                Collection<List<String>> dataSet = getDistrictDetailDataSet(districtData);
                exportExcel(title,titleHead,headers,dataSet,fos,null);
            }else {
                return sendResult(ResultCode.CODE_405.code,ResultCode.CODE_405.msg,null);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return  sendResult(ResultCode.CODE_401.code,ResultCode.CODE_401.msg,null);
        }
        System.out.println(request.getRequestURL().toString());
        String url = request.getRequestURL().toString().replace("/ctrl/districtCount/exportDistrictDetail","")+"/upload/file/"+title+".xls";
        result.put("url",url);
        return sendResult(ResultCode.CODE_200.code,ResultCode.CODE_200.msg,result);
    }

4.输出excel表格比较

   首先需要说明的是,笔者对ireport的使用仅仅只是初步认识和阶段,ireport的强大之处并没有深入研究,笔者使用ireport 导出的excel表格并没有达到预想的结果,主要有以下几点,

  一,整个页面背景为白色,而不是透明显示,使用最笨的方法是通过在ireport中设置页面边距来,来使不存在数据的页面边界透明显示。调试ireport到合适的页面大小很苦逼,如果是动态的数据就更是不可取。不知道还有没有别的方法能达到效果。这也使不得不放弃ireport。

二,导出的excel表格中的斜线无法显示

三,动态数据表格中实现合并单元格功能无法实现;在实际项目需求中,尤其是在动态数据中需要对动态的数据进行合并单元格操作,在ireport中找不到解决的方法。

使用poi完全可以随心所欲的去设计表格,相同格式的excel表格可以公用一个方法,传入不同的参数即可;当遇到格式复杂的表格(例如复杂表头),可以单独重写方法。在ireport中出现的问题,poi都能得到完美解决。

5.综上所述,项目的需求,以及各自的优缺点,笔者最终选择了poi。个人觉得ireport还是比较适合非开发人员去完成表格的导出功能,在ireport中直接导出的表格还是很不错,操作简单,一般的非开发人员使用ireport可以得到需要的各种excel表格,或者pdf格式文档。poi插件可以适合任意excel表格的输出,完全满足开发需求。


一、 POI简介

            Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

二、 HSSF概况

            HSSF 是Horrible SpreadSheet Format的缩写,通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。

三、 POI EXCEL文档结构类

            HSSFWorkbook excel文档对象

            HSSFSheet excel的sheet HSSFRow excel的行

            HSSFCell excel的单元格 HSSFFont excel字体

            HSSFName 名称 HSSFDataFormat 日期格式

            HSSFHeader sheet头

            HSSFFooter sheet尾

            HSSFCellStyle cell样式

            HSSFDateUtil 日期

            HSSFPrintSetup 打印

            HSSFErrorConstants 错误信息表

四、 EXCEL常用操作方法

  1、 得到Excel常用对象           
[c-sharp]  view plain copy print ?
  1. POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));   
  2. //得到Excel工作簿对象    
  3. HSSFWorkbook wb = new HSSFWorkbook(fs);  
  4. //得到Excel工作表对象    
  5. HSSFSheet sheet = wb.getSheetAt(0);   
  6. //得到Excel工作表的行    
  7. HSSFRow row = sheet.getRow(i);  
  8. //得到Excel工作表指定行的单元格    
  9. HSSFCell cell = row.getCell((short) j);  
  10. cellStyle = cell.getCellStyle();//得到单元格样式  
 2、建立Excel常用对象
[c-sharp]  view plain copy print ?
  1. HSSFWorkbook wb = new HSSFWorkbook();//创建Excel工作簿对象   
  2. HSSFSheet sheet = wb.createSheet("new sheet");//创建Excel工作表对象     
  3. HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行   
  4. cellStyle = wb.createCellStyle();//创建单元格样式   
  5. row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格   
  6. row.createCell((short)0).setCellValue(1); //设置Excel工作表的值  
3、设置sheet名称和单元格内容
[c-sharp]  view plain copy print ?
  1. wb.setSheetName(1, "第一张工作表",HSSFCell.ENCODING_UTF_16);          
  2. cell.setEncoding((short) 1);      
  3. cell.setCellValue("单元格内容");  
4、取得sheet的数目 
[c-sharp]  view plain copy print ?
  1. wb.getNumberOfSheets()   
5、  据index取得sheet对象
[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet = wb.getSheetAt(0);  
6、取得有效的行数
[c-sharp]  view plain copy print ?
  1. int rowcount = sheet.getLastRowNum();  
7、取得一行的有效单元格个数
[c-sharp]  view plain copy print ?
  1. row.getLastCellNum();    

8、单元格值类型读写

[c-sharp]  view plain copy print ?
  1. cell.setCellType(HSSFCell.CELL_TYPE_STRING); //设置单元格为STRING类型   
  2. cell.getNumericCellValue();//读取为数值类型的单元格内容  

 

9、设置列宽、行高

[c-sharp]  view plain copy print ?
  1. sheet.setColumnWidth((short)column,(short)width);      
  2. row.setHeight((short)height);    

 

10、添加区域,合并单元格

[c-sharp]  view plain copy print ?
  1. Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo  
  2. ,(short)columnTo);//合并从第rowFrom行columnFrom列   
  3. sheet.addMergedRegion(region);// 到rowTo行columnTo的区域      
  4. //得到所有区域       
  5. sheet.getNumMergedRegions()   

 

11、保存Excel文件

[c-sharp]  view plain copy print ?
  1. FileOutputStream fileOut = new FileOutputStream(path);   
  2. wb.write(fileOut);   

 

12、根据单元格不同属性返回字符串数值

[c-sharp]  view plain copy print ?
  1. public String getCellStringValue(HSSFCell cell) {      
  2.         String cellValue = "";      
  3.         switch (cell.getCellType()) {      
  4.         case HSSFCell.CELL_TYPE_STRING://字符串类型   
  5.             cellValue = cell.getStringCellValue();      
  6.             if(cellValue.trim().equals("")||cellValue.trim().length()<=0)      
  7.                 cellValue=" ";      
  8.             break;      
  9.         case HSSFCell.CELL_TYPE_NUMERIC: //数值类型   
  10.             cellValue = String.valueOf(cell.getNumericCellValue());      
  11.             break;      
  12.         case HSSFCell.CELL_TYPE_FORMULA: //公式   
  13.             cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);      
  14.             cellValue = String.valueOf(cell.getNumericCellValue());      
  15.             break;      
  16.         case HSSFCell.CELL_TYPE_BLANK:      
  17.             cellValue=" ";      
  18.             break;      
  19.         case HSSFCell.CELL_TYPE_BOOLEAN:      
  20.             break;      
  21.         case HSSFCell.CELL_TYPE_ERROR:      
  22.             break;      
  23.         default:      
  24.             break;      
  25.         }      
  26.         return cellValue;      
  27.     }     

 

13、常用单元格边框格式

[c-sharp]  view plain copy print ?
  1. HSSFCellStyle style = wb.createCellStyle();      
  2. style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框        
  3. style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框        
  4. style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框        
  5. style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框    

 

14、设置字体和内容位置

[c-sharp]  view plain copy print ?
  1. HSSFFont f  = wb.createFont();      
  2. f.setFontHeightInPoints((short) 11);//字号       
  3. f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗       
  4. style.setFont(f);      
  5. style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中       
  6. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中       
  7. style.setRotation(short rotation);//单元格内容的旋转的角度       
  8. HSSFDataFormat df = wb.createDataFormat();      
  9. style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式       
  10. cell.setCellFormula(string);//给单元格设公式       
  11. style.setRotation(short rotation);//单元格内容的旋转的角度   

 

15、插入图片

[c-sharp]  view plain copy print ?
  1. //先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray       
  2.       ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();      
  3.       BufferedImage bufferImg = ImageIO.read(new File("ok.jpg"));      
  4.       ImageIO.write(bufferImg,"jpg",byteArrayOut);      
  5. //读进一个excel模版       
  6. FileInputStream fos = new FileInputStream(filePathName+"/stencil.xlt");       
  7. fs = new POIFSFileSystem(fos);      
  8. //创建一个工作薄       
  9. HSSFWorkbook wb = new HSSFWorkbook(fs);      
  10. HSSFSheet sheet = wb.getSheetAt(0);      
  11. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();      
  12. HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);           
  13. patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));    

 

16、调整工作表位置

[c-sharp]  view plain copy print ?
  1. HSSFWorkbook wb = new HSSFWorkbook();     
  2. HSSFSheet sheet = wb.createSheet("format sheet");     
  3. HSSFPrintSetup ps = sheet.getPrintSetup();     
  4. sheet.setAutobreaks(true);     
  5. ps.setFitHeight((short)1);     
  6. ps.setFitWidth((short)1);   
  

 

17、设置打印区域

[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet = wb.createSheet("Sheet1");     
  2. wb.setPrintArea(0, "$A$1:$C$2");    

 

18、标注脚注

[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet = wb.createSheet("format sheet");     
  2. HSSFFooter footer = sheet.getFooter()     
  3. footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );   

 

19、在工作单中清空行数据,调整行位置

[c-sharp]  view plain copy print ?
  1. HSSFWorkbook wb = new HSSFWorkbook();     
  2. HSSFSheet sheet = wb.createSheet("row sheet");     
  3. // Create various cells and rows for spreadsheet.      
  4. // Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)      
  5. sheet.shiftRows(5, 10, -5);    

 

20、选中指定的工作表

[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet = wb.createSheet("row sheet");     
  2. heet.setSelected(true);     

 

21、工作表的放大缩小

 

[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet1 = wb.createSheet("new sheet");     
  2. sheet1.setZoom(1,2);   // 50 percent magnification    

 

22、头注和脚注

[c-sharp]  view plain copy print ?
  1. HSSFSheet sheet = wb.createSheet("new sheet");     
  2. HSSFHeader header = sheet.getHeader();     
  3. header.setCenter("Center Header");     
  4. header.setLeft("Left Header");     
  5. header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +     
  6. HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");  

 

23、自定义颜色

[c-sharp]  view plain copy print ?
  1. HSSFCellStyle style = wb.createCellStyle();     
  2. style.setFillForegroundColor(HSSFColor.LIME.index);     
  3. style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);     
  4. HSSFFont font = wb.createFont();     
  5. font.setColor(HSSFColor.RED.index);     
  6. style.setFont(font);     
  7. cell.setCellStyle(style);     

24、填充和颜色设置

[c-sharp]  view plain copy print ?
  1. HSSFCellStyle style = wb.createCellStyle();     
  2. style.setFillBackgroundColor(HSSFColor.AQUA.index);     
  3. style.setFillPattern(HSSFCellStyle.BIG_SPOTS);     
  4. HSSFCell cell = row.createCell((short) 1);     
  5. cell.setCellValue("X");     
  6. style = wb.createCellStyle();     
  7. style.setFillForegroundColor(HSSFColor.ORANGE.index);     
  8. style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);     
  9. cell.setCellStyle(style);   

25、强行刷新单元格公式

[c-sharp]  view plain copy print ?
  1. HSSFFormulaEvaluator eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);    
  2. private static void updateFormula(Workbook wb,Sheet s,int row){     
  3.         Row r=s.getRow(row);     
  4.         Cell c=null;     
  5.         FormulaEcaluator eval=null;     
  6.         if(wb instanceof HSSFWorkbook)     
  7.             eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);     
  8.         else if(wb instanceof XSSFWorkbook)     
  9.             eval=new XSSFFormulaEvaluator((XSSFWorkbook) wb);     
  10.         for(int i=r.getFirstCellNum();i<r.getLastCellNum();i++){     
  11.             c=r.getCell(i);     
  12.             if(c.getCellType()==Cell.CELL_TYPE_FORMULA)     
  13.                 eval.evaluateFormulaCell(c);     
  14.         }     
  15.     }    

说明:FormulaEvaluator提供了evaluateFormulaCell(Cell cell)方法,计算公式保存结果,但不改变公式。而evaluateInCell(Cell cell) 方法是计算公式,并将原公式替换为计算结果,也就是说该单元格的类型不在是Cell.CELL_TYPE_FORMULA而是Cell.CELL_TYPE_NUMBERIC。HSSFFormulaEvaluator提供了静态方法evaluateAllFormu

laCells(HSSFWorkbook wb) ,计算一个Excel文件的所有公式,用起来很方便。 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------poi方法总结

-.设置不显示excel网格线 
  sheet.setDisplayGridlines(false);其中sheet是Sheet对象 
2.设置excel单元格中的内容换行 
  cellStyle.setWrapText(true);其中cellStyle是WorkBook创建的CellStyle对象,然后将cellStyle设置到要换行的Cell对象,最后在要换行的对象(一般为字符串)加入"/r/n"。如 
topTile.append("/r/n" +"cellContent"); 

3.单元格的合并 
  sheet.addMergedRegion(new CellRangeAddress(0, 4, 0, 2));本示例为合并4行2列 

4.设置页眉和页脚的页数 
    HSSFHeader header = sheet.getHeader(); 
    header.setCenter("Center Header"); 
    header.setLeft("Left Header"); 
    header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + 
    HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16"); 

  HSSFFooter footer = (HSSFFooter )sheet.getFooter() 
  footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() ); 

5.使得一个Sheet适合一页 
  sheet.setAutobreaks(true); 
6.设置放大属性(Zoom被明确为一个分数,例如下面的75%使用3作为分子,4作为分母) 
  sheet.setZoom(3,4);   

7.设置打印 
  HSSFPrintSetup print = (HSSFPrintSetup) sheet.getPrintSetup(); 
  print.setLandscape(true);//设置横向打印 
  print.setScale((short) 70);//设置打印缩放70% 
  print.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);//设置为A4纸张 
  print.setLeftToRight(true);//設置打印顺序先行后列,默认为先列行            
  print.setFitHeight((short) 10);设置缩放调整为10页高 
  print.setFitWidth((short) 10);设置缩放调整为宽高 

  sheet.setAutobreaks(false); 
  if (i != 0 && i % 30 == 0) 
      sheet.setRowBreak(i);//設置每30行分頁打印 

8.反复的行和列(设置打印标题) 
  HSSFWorkbook wb = new HSSFWorkbook(); 
  wb.setRepeatingRowsAndColumns(0, 0, 12, 1, 6);//设置1到12列,行1到6每一页重复打印 

9.调整单元格宽度 
  sheet.setAutobreaks(true); 
  sheet.setColumnWidth((short)i,colsWidth[i]); //设定单元格长度 
    sheet.autoSizeColumn((short) i);//自动根据长度调整单元格长度 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值