首先需要导入包

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

然后写方法,由于我使用的框架全部是spring

此处我只写入实现层和控制层代码

@Override
public InputStream loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, Map<String, Object> operator) {
NPOIFSFileSystem fs = null;
Workbook workbook = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream(); try {
File file = new File(this.getClass().getResource("/../../resource/matComYearPlan.xls").getFile());
FileInputStream inputStream = new FileInputStream(file);
fs = new NPOIFSFileSystem(inputStream);
workbook = (Workbook) new HSSFWorkbook(fs.getRoot(), true); Sheet sheet = workbook.getSheetAt(0); List<Map<String, Object>> matYearPlanList = selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);
List<Map<String, Object>> matTypedmCodeList = dmCodeService.selectDmCodeByGroupName("MAT_TYPE_", operator);
List<Map<String, Object>> processStatusTypedmCodeList = dmCodeService.selectDmCodeByGroupName("PROCESS_STATUS_TYPE_", operator);
List<Map<String, Object>> matBudgetCatList = matBudgetCatService.selectMatBudgetCat(1, -1, operator);
List<Map<String, Object>> matSpecCatList = matSpecCatService.selectMatSpecCat(1, -1, operator); Map<String, Object> matYearPlan;
String MAT_BUDGET_CAT_NAME_ = "";
String PARENT_MAT_BUDGET_CAT_ID_;
for (int i = 0; i < matYearPlanList.size(); i++) {
matYearPlan = matYearPlanList.get(i);
Row row = sheet.createRow(i + 1); row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));
row.createCell(1).setCellValue((String) matYearPlan.get("MAT_DESC_"));
row.createCell(2).setCellValue((String) matYearPlan.get("LARGE_MAT_CAT_CODE_"));
row.createCell(3).setCellValue((String) matYearPlan.get("UNIT_")); if (matYearPlan.get("PLANNED_PRICE_") != null) {
row.createCell(4).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue());
}
if (matYearPlan.get("AMOUNT_") != null) {
row.createCell(5).setCellValue(((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());
}
if (matYearPlan.get("PLANNED_PRICE_") != null && matYearPlan.get("AMOUNT_") != null) {
row.createCell(6).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue() * ((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());
}
if (matYearPlan.get("MAT_TYPE_") != null) {
for (int j = 0; j < matTypedmCodeList.size(); j++) {
Map<String, Object> matTypedmCode = matTypedmCodeList.get(j);
if ((((BigDecimal) matYearPlan.get("MAT_TYPE_")).intValue()) == (((BigDecimal) matTypedmCode.get("CODE_"))).intValue()) {
row.createCell(7).setCellValue((String) matTypedmCode.get("VALUE_"));
break;
}
}
}
row.createCell(8).setCellValue((String) matYearPlan.get("DEPT_NAME_")); for (int j = 0; j < matBudgetCatList.size(); j++) {
Map<String, Object> matBudgetCat = matBudgetCatList.get(j);
if (((String) matYearPlan.get("MAT_BUDGET_CAT_ID_")).equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {
MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_");
PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");
while (PARENT_MAT_BUDGET_CAT_ID_ != null) {
for (int k = 0; k < matBudgetCatList.size(); k++) {
matBudgetCat = matBudgetCatList.get(k);
if (PARENT_MAT_BUDGET_CAT_ID_.equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {
MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_") + "/" + MAT_BUDGET_CAT_NAME_;
PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");
break;
}
}
}
row.createCell(9).setCellValue("/" + MAT_BUDGET_CAT_NAME_ + "/");
break;
}
}
if (matYearPlan.get("MAT_SPEC_CAT_CODE_") != null) {
for (int j = 0; j < matSpecCatList.size(); j++) {
Map<String, Object> matSpecCat = matSpecCatList.get(j);
if (((String) matYearPlan.get("MAT_SPEC_CAT_CODE_")).equals((String) matSpecCat.get("CODE_"))) {
row.createCell(10).setCellValue((String) matSpecCat.get("VALUE_"));
break;
}
}
}
if (matYearPlan.get("PROCESS_STATUS_") != null) {
for (int j = 0; j < processStatusTypedmCodeList.size(); j++) {
Map<String, Object> processStatusTypedmCode = processStatusTypedmCodeList.get(j);
if ((((BigDecimal) matYearPlan.get("PROCESS_STATUS_")).intValue()) == (((BigDecimal) processStatusTypedmCode.get("CODE_")).intValue())) {
row.createCell(11).setCellValue((String) processStatusTypedmCode.get("VALUE_"));
break;
}
}
}
} workbook.write(baos);
baos.flush();
byte[] bytes = baos.toByteArray(); return new ByteArrayInputStream(bytes, 0, bytes.length);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
finally {
try {
fs.close();
workbook.close();
baos.close();
}
catch (IOException e) {
}
}
}

其中有个selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);方法是我的业务方法,可根据需要改变自己实际的参数,对自己的代码进行修改

 Row row = sheet.createRow(i + 1);
row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));
这两句代码是与其他人不同的地方,有些人的代码是getRow(),getCell()。那样很可能会报空指针异常,如果以前有数据只是对其覆盖可以使用,如果以前没有数据,是动态生成的最后使用create方法 另外我在代码中大量使用了String造型,而不是toString()方法,因为String相对于tostring()方法更安全,而其不会报空指针异常。而toString()方法有时会需要重写,不是那么安全。
=null.toString()会有空指针异常,而 =(String)null则不会。
//控制层代码
@RequestMapping(value = "loadMatComYearPlanXls")
public void loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, HttpServletRequest request, HttpServletResponse response, HttpSession session) {
try {
Map<String, Object> operator = getOperator(session); InputStream inputStream = matYearPlanService.loadMatComYearPlanXls(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, operator);
response.reset();
String fileName = URLEncoder.encode("厂矿年计划表.xls", "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
ServletOutputStream out = response.getOutputStream();
byte[] content = new byte[65535];
int length = 0;
if (inputStream != null) {
while ((length = inputStream.read(content)) != -1) {
out.write(content, 0, length);
}
}
out.flush();
out.close();
}
catch (Exception e) {
insertBizLog("业务", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 1, e.getMessage(), request, session);
logger.error(e.getMessage(), e);
}
insertBizLog("业务", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 0, null, request, session);
}

控制层主要是调用实现层代码。主要的POI代码在实现层,网上有很多这类代码,只是我自己对空指针的处理做了自己的改变,网络上说的很多方法不全。

另外这这次的业务实现里,有个BigDecimal类型,http://baike.baidu.com/link?url=abJmNaoqJGE0RbYpjmOCB4otjPPqhpwYPSlMkVwPV6c_0V8I42VljBvaDtCI6h-xNIn5N5CFjrWPvvz4A132lK

由于将值放进map时都是Object类型,但在取出时,它的类型并没有丢失,所以在.intValue(),和.doubleValue()取值时,与String不同,同时需要做空值处理

如果不想使用造型可以使用parse解析。

中间有段代码是做的树形的循环递归遍历。

//在jsp页面的调用
function _loadMatComYearPlanXls() {
var MAT_BUDGET_CAT_ID_ = '';
var records = Ext.getCmp('matBudgetCatPanel').getSelectionModel().getSelection();
if (records.length != 0) {
MAT_BUDGET_CAT_ID_ = records[0].get('MAT_BUDGET_CAT_ID_');
}
window.open('loadMatComYearPlanXls.do?YEAR_=' + Ext.getCmp('YEAR_').getSubmitValue() + '&MONTH_=' + Ext.getCmp('MONTH_').getSubmitValue() + '&MAT_TYPE_=' + Ext.getCmp('MAT_TYPE_').getSubmitValue() + '&MAT_YEAR_PLN_BATCH_ID_=' + Ext.getCmp('MAT_YEAR_PLN_BATCH_ID_').getSubmitValue() + '&DEPT_CODE_=' + Ext.getCmp('DEPT_CODE_').getSubmitValue() + '&MAT_NO_=' + Ext.getCmp('MAT_NO_').getSubmitValue() + '&MAT_DESC_=' + Ext.getCmp('MAT_DESC_').getSubmitValue() + '&MAT_SPEC_CAT_CODE_=' + Ext.getCmp('MAT_SPEC_CAT_CODE_').getSubmitValue() + '&COM_CODE_=' + COM_CODE_ + '&MAT_BUDGET_CAT_ID_=' + MAT_BUDGET_CAT_ID_, '_blank', 'width=40,height=30,resizable=yes,scrollbars=yes');
}

JSP页面只是调用控制层代码,如果自己有需要,可以按自己的方法传参调用。

poi的API文档:http://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html#SXSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook)

对最后一行需要数值总计的处理:

if (i == matContractStockIoList.size() - 1) {
row = sheet.createRow(i + 2);
row.createCell(0).setCellValue("合计 :");
row.createCell(5).setCellFormula("SUM(F2:F" + (i + 2) + ")");
row.createCell(6).setCellFormula("SUM(G2:G" + (i + 2) + ")");
}

欢迎大家阅览,多多评论其中的不足!!

为工程师之路添砖加瓦!!

 

Java poi读取,写入Excel,处理row和cell可能为空的情况的更多相关文章

  1. Java poi读取,写入Excel2003

    Java poi读取,写入Excel2003 相关阅读:poi读写Excel2007:http://www.cnblogs.com/gavinYang/p/3576741.htmljxl读写excel ...

  2. Java poi读取,写入Excel2007

    Java poi读取,写入Excel2007 相关阅读:poi读写Excel2003:http://www.cnblogs.com/gavinYang/p/3576739.htmljxl读写excel ...

  3. POI读取/写入Excel文件

    import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...

  4. poi读取写入word【未完,待续】

    , [项目实战]Java POI之Word导出经典案例一 Java POI 读取word文件 POI-对于WORD的操作(一)

  5. Java——poi读取Excel文件

    1.创建文件流,打开EXCEL文件 FileInputStream excelFile = new FileInputStream(excelPath); XSSFWorkbook workbook ...

  6. Java入门开发POI读取导入Excel文件

    Apache POI是Apache开发的开源的跨平台的 Java API,提供API给Java程序对Microsoft Office格式档案进行各种操作. POI中Excel操作很简单,主要类有 HS ...

  7. Java POI 读取Excel数据转换为XML格式

    1.首先要下载poi相关的包:http://poi.apache.org/  ,以下是所需的jar包 2.贴上详细的代码 public class ExcelToXml { /** * 将excel的 ...

  8. JXL读取,写入Excel

    JXL读取,写入Excel2003 相关阅读:poi 读写excel2003:http://www.cnblogs.com/gavinYang/p/3576739.htmlpoi 读写excel200 ...

  9. java POI实现向Excel中插入图片

          做Web开发免不了要与Excel打交道.今天老大给我一个任务-导出Excel.开始想的还是蛮简单的,无非就是查找,构建Excel,response下载即可.但是有一点不同,就是要加入图片, ...

随机推荐

  1. Winform布局方式

    一.默认布局 ★可以加panel,也可以不加: ★通过鼠标拖动控件的方式,根据自己的想法布局.拖动控件的过程中,会有对齐的线,方便操作: ★也可选中要布局的控件,在工具栏中有对齐工具可供选择,也有调整 ...

  2. 数据表格 - DataGrid - 查询

    toolbar头部工具栏 <script type="text/javascript"> $(function () { $("#datagrid" ...

  3. [技术分享] centos如何挂载Windows共享文件

    http://www.iyunv.com/thread-294209-1-1.html 最为linux的初学者,自我感觉都会使用Windows中的文件.在Windows与linux之间互传文件是一个问 ...

  4. 6款程序员不得不爱的bootstrap模板

    Bootstrap是基于jQuery框架开发的,它在jQuery框架的基础上进行了更为个性化和人性化的完善,形成一套自己独有的网站风格,并兼容大 部分jQuery插件.Bootstrap中包含了丰富的 ...

  5. 【跟着子迟品 underscore】如何优雅地写一个『在数组中寻找指定元素』的方法

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  6. 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!

    背景 目前市场上有很多表单美化的UI,做的都挺不错,但是他们都有一个共同点,那就是90%以上都是前端工程师开发的,导致我们引入这些UI的时候,很难和程序绑定.所以作为程序员的我,下了一个决定!我要自己 ...

  7. RTC时钟

    1.设置时间之前取消备份区域(BKP)写保护 主要有两部分组成 1.用来和APB1总线对接,对其进行读写操作 2. 预分频模块:在RTC_CR设置相应的允许,位每个TR_CLK周期中RTC产生一个中断 ...

  8. Android异步消息处理机制完全解析,带你从源码的角度彻底理解(转)

    开始进入正题,我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一 ...

  9. 篇一:JSON格式转换(一)

    JSON.parse()和JSON.stringify()的使用 1.JSON.parse() 用于从一个字符串中解析出json 对象.例如 var str='{"name":&q ...

  10. C#-和时间有关的计算代码、时间相减 得到天数、小时、分钟、秒差

    asp.net(C#)时间相减 得到天数.小时.分钟.秒差   asp.net(C#)时间相减 得到天数.小时.分钟.秒差   DateTime dtone = Convert.ToDateTime( ...