`
immortal2512
  • 浏览: 44018 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

poi注意事项

    博客分类:
  • java
阅读更多

1、设置分页符的bug。
  poi里的HSSFSheet类提供了setRowBreak方法可以设置Sheet的分页符。
  Bug:如果你要设置分页符的Sheet是本来就有的,并且你没有在里面插入过分页符,那么调用setRowBreak时POI会抛出空指针的异常。
  解决方法:在Excel里给这个sheet插入一个分页符,用POI打开后再把它删掉,然后你就可以随意插入分页符了。
  如果sheet是由poi生成的则没有这个问题。我跟踪了setRowBreak的源代码,发现是Sheet.java下的PageBreakRecord rowBreaks这个变量在搞鬼,如果Sheet里原来没有分页符,开发这个模块的那位兄台忘了为这个对象new实例,所以只能我们先手工给Excel插入一个分页符来触发poi为rowBreaks创建实例。
  2、如何拷贝行。
  我在gmane.org的poi用户论坛翻遍了每个相关的帖子,找遍了api,也没看到一个拷贝行的方法,没办法,只能自己写:
  //注:this.fWorkbook是一个HSSHWorkbook,请自行在外部new
  public void copyRows(String pSourceSheetName, String pTargetSheetName, int pStartRow, int pEndRow, int pPosition)
  {
  HSSFRow sourceRow = null;
  HSSFRow targetRow = null;
  HSSFCell sourceCell = null;
  HSSFCell targetCell = null;
  HSSFSheet sourceSheet = null;
  HSSFSheet targetSheet = null;
  Region region = null;
  int cType;
  int i;
  short j;
  int targetRowFrom;
  int targetRowTo;
  if ((pStartRow == -1) || (pEndRow == -1))
  {
  return;
  }
  sourceSheet = this.fWorkbook.getSheet(pSourceSheetName);
  targetSheet = this.fWorkbook.getSheet(pTargetSheetName);
  //拷贝合并的单元格
  for (i = 0; i < sourceSheet.getNumMergedRegions(); i++)
  {
  region = sourceSheet.getMergedRegionAt(i);
  if ((region.getRowFrom() = pStartRow) && (region.getRowTo() <= pEndRow))
  {
  targetRowFrom = region.getRowFrom() - pStartRow + pPosition;
  targetRowTo = region.getRowTo() - pStartRow + pPosition;
  region.setRowFrom(targetRowFrom);
  region.setRowTo(targetRowTo);
  targetSheet.addMergedRegion(region);
  }
  }
  //设置列宽
  for (i = pStartRow; i <= pEndRow; i++)
  {
  sourceRow = sourceSheet.getRow(i);
  if (sourceRow != null)
  {
  for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++)
  {
  targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));
  }
  break;
  }
  }
  //拷贝行并填充数据
  for (;i <= pEndRow; i++)
  {
  sourceRow = sourceSheet.getRow(i);
  if (sourceRow == null)
  {
  continue;
  }
  targetRow = targetSheet.createRow(i - pStartRow + pPosition);
  targetRow.setHeight(sourceRow.getHeight());
  for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++)
  {
  sourceCell = sourceRow.getCell(j);
  if (sourceCell == null)
  {
  continue;
  }
  targetCell = targetRow.createCell(j);
  targetCell.setEncoding(sourceCell.getEncoding());
  targetCell.setCellStyle(sourceCell.getCellStyle());
  cType = sourceCell.getCellType();
  targetCell.setCellType(cType);
  switch (cType)
  {
  case HSSFCell.CELL_TYPE_BOOLEAN:
  targetCell.setCellValue(sourceCell.getBooleanCellValue());
  break;
  case HSSFCell.CELL_TYPE_ERROR:
  targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
  break;
  case HSSFCell.CELL_TYPE_FORMULA:
  //parseFormula这个函数的用途在后面说明
  targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));
  break;
  case HSSFCell.CELL_TYPE_NUMERIC:
  targetCell.setCellValue(sourceCell.getNumericCellValue());
  break;
  case HSSFCell.CELL_TYPE_STRING:
  targetCell.setCellValue(sourceCell.getStringCellValue());
  break;
  }
  }
  }
  }
  这个函数有两个问题暂时无法解决:
  a、只能在同一个Workbook里面使用,跨Workbook总是拷不过去,不知道为什么?
  b、由于在拷贝行时也把行高也拷过去了,如果往这些单元格里写入的数据长度超过单元格长度,那么他们不会自动调整行高!
  有哪位大侠知道上面两个问题任意一个的解决方法,请第一时间通知我!!!
  3、公式的问题。
  POI对Excel公式的支持是相当好的,但是我发现一个问题,如果公式里面的函数不带参数,比如now()或today(),那么你通过getCellFormula()取出来的值就是now(ATTR(semiVolatile))和today(ATTR(semiVolatile)),这样的值写入Excel是会出错的,这也是我上面copyRow的函数在写入公式前要调用parseFormula的原因,parseFormula这个函数的功能很简单,就是把ATTR(semiVolatile)删掉,我把它的代码贴出来:
  private String parseFormula(String pPOIFormula)
  {
  final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
  StringBuffer result = null;
  int index;
  result = new StringBuffer();
  index = pPOIFormula.indexOf(cstReplaceString);
  if (index = 0)
  {
  result.append(pPOIFormula.substring(0, index));
  result.append(pPOIFormula.substring(index + cstReplaceString.length()));
  }
  else
  {
  result.append(pPOIFormula);
  }
  return result.toString();
  }
  至于为什么会出现ATTR(semiVolatile),希望哪位大侠现身跟我解释一下。
  4、向Excel写入图片的问题。
  我上poi论坛查相关帖子,得到两种结论:1、不支持写入图片;2、支持写入图片,通过EscherGraphics2d这个Class实现。于是我就去查EscherGraphics2d这个Class,发现这个Class提供了N个drawImage方法,喜出望外的我开始写代码,结果调了一天,一直看不到效果,黔驴技穷的我在万般无奈下只好跟踪进drawImage这个函数内部,经过N个函数调用后在最底层函数发现了最终答案(偶当场暴走!!!):
  public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
  int sx2, int sy2, Color bgColor, ImageObserver imageobserver)
  {
  if (logger.check( POILogger.WARN ))
  logger.log(POILogger.WARN,"drawImage() not supported");
  return true;
  }
  所以我强烈建议大家,以后使用第三方开发包一定尽量下载它的源代码,这样你在碰到问题时,看看它的的内部是怎么实现的,很多时候就可以不必重蹈我的覆辙了。既然POI不能写入图片,那我们只能把目光投向JXL,我用JXL写入图片功能是实现了,付出的代价是now()和today()这些函数丢失掉了,鱼与熊掌不能兼得吧,至于怎么解决JXL公式的问题,到下面这个帖子里和我一起守株待兔吧:
  http://community.csdn.net/Expert/topic/3569/3569340.xml?temp=.8480646

分享到:
评论

相关推荐

    POI 合并单元格 及 注意事项

    POI 合并单元格 及 注意事项

    POI预处理.docx

    包含POI数据的预处理方法,在arcmap中的具体操作步骤以及在具体操作过程中需要注意的一些注意事项

    Java用POI API实现对Excel表的读取与写入,包含对数据库的读写,亲测有效

    本下项目包包含以下内容: ...注意事项: 1、需要导入maven工程 2、使用druid连接池,需要自己修改一下里面的连接配置 3、数据库表需要自己手动创建一下 4、支持.xlsx格式 有不懂的可以私信我或者+q:825037759

    凯立德导航升级注意事项

    2、下载 [凯立德地图(2C21J0C)].part1.rar 、[凯立德地图(2C21J0C)].part2.rar和 [凯立德地图(2C21J0C)].part3.rar ,使用winrar对 [凯立德地图(2C21J0C)].part1.rar 进行解压,解压后有1个文件夹 poi_data ...

    Java Web使用POI导出Excel的方法详解

    主要介绍了Java Web使用POI导出Excel的方法,结合实例形式详细分析了Java Web使用POI导出Excel的具体操作步骤、实现技巧与相关注意事项,需要的朋友可以参考下

    osmpoi:一个易于使用的基于 Web 的 OpenStreetMap POI 编辑器

    请注意以下事项。 由于它目前并不安全,请使用它只是为了在目前的测试。 当前编辑目标不是 OpenStreetMap 本身,而是测试地图 用法 将您的应用程序注册到 根据需要编辑 config.rb.sample 并将其另存为 config.rb...

    JAVABOS物流系统SSH源码 JAVABOSWLXTSSH.rar

    JAVABOS物流系统SSH源码 源码描述: 一、源码介绍 使用ssh,mysql实现。bos.sql里面存放的是sql建表语句。 二、主要功能 - 每个用户对应不同的角色,每个角色对应...三、注意事项 开发环境为eclipse,数据库为mysql

    plugin-prophet:先知插件

    开发者注意事项 该项目现在包含lib-battle作为子模块,必要时使用git submodule init 、 git submodule sync或git submodule update 。 重要提示:在发布新版本之前,请务必检查子模块是否已更新。 致谢 感谢这个...

    CSS的pointer-events属性详细介绍(作用和注意事项)

    而本文要说的pointer-events的风格更像JavaScript,它能够: ...阻止缺省鼠标指针的显示3.阻止CSS里的hover和active状态的变化触发事件4....一个CSS属性能做所有的这么多事情! The CSS 这个pointer-events属性有很多可以...

    POIMobile:运行Oracle Mobile Application Framework的示例应用程序

    以下是运行该应用程序的一些注意事项: 要求 Java 8 安装了Oracle Mobile Application插件的JDeveloper 12c: : 安装了Android或IOS模拟器 运行xy-inc应用程序: : 设定 在JDeveloper中,更改REST POIREST连接 ...

    c#WinFrom高性能地图源码

    一、源码特点 1、对地图Web Service API 的一些封装,每个接口返回的都是JObject类型(参见Json.NET) 2、提供一系列可以在Winform中使用的...二、注意事项 1、开发环境为Visual Studio 2015,使用.net 4.0开发。

    c#WinFrom高性能百度地图源码

    一、源码特点 1、对百度地图Web Service API 的一些封装,每个接口返回的都是JObject类型(参见Json.NET) 2、提供一系列可以在Winform中使用...二、注意事项 1、开发环境为Visual Studio 2015,使用.net 4.0开发。

    WinFrom高性能百度地图源码

    一、源码特点 1、对百度地图Web Service API 的一些封装,每个接口返回的都是JObject类型(参见Json.NET) 2、提供一系列可以在Winform中使用...二、注意事项 1、开发环境为Visual Studio 2015,使用.net 4.0开发。

    百度地图 功能模块完整版 开发指南

    (6)其他注意事项请参考【CloudSearchDemoViewController.mm文件内的注释部分】; (7)LBS.云检索使用方法请参考开发指南“LBS云服务”部分; (8)详细了解LBS.云,欢迎访问:...

Global site tag (gtag.js) - Google Analytics