NPOI用Excel模板导出Excel文件(二)导入模板

三、需求分析

图片 1图片 2

 1     /**
 2      * 第四个sheet页:人才需求情况调查表
 3      * 
 4      * @param workbook
 5      * @param talentFlows
 6      */
 7     private void addalentDemands(HSSFWorkbook workbook, List<BaseTalentDemandAnalysisGridVo> talentDemands)
 8             throws IllegalArgumentException, IllegalAccessException {
 9         Sheet talentDemandSheet = workbook.getSheetAt(3);
10         Row talentDemandRow = talentDemandSheet.getRow(4);
11         // 如果数据大于模板中的行数,插入行并复制第一行数据的格式
12         if (talentDemands.size() > 5) {
13             // 插入行,5是模板中已有的行数
14             talentDemandSheet.shiftRows(5, talentDemandSheet.getLastRowNum(), talentDemands.size() - 5, true, false);
15             Row sourceRow = talentDemandSheet.getRow(4);
16             for (int i = 0; i < talentDemands.size() - 5; i++) {
17                 Row newRow = talentDemandSheet.createRow(4 + i + 1);
18                 newRow.setHeight(sourceRow.getHeight());
19                 for (int j = 0; j < sourceRow.getLastCellNum(); j++) {
20                     Cell templateCell = sourceRow.getCell(j);
21                     if (templateCell != null) {
22                         Cell newCell = newRow.createCell(j);
23                         copyCell(templateCell, newCell);
24                     }
25                 }
26             }
27         }
28         // 填充数据
29         for (int i = 0; i < talentDemands.size(); i++) {
30             talentDemandRow = talentDemandSheet.getRow(4 + i);
31             talentDemandRow.getCell(0).setCellValue(talentDemands.get(i).getPositionTitle());
32             talentDemandRow.getCell(2).setCellValue(talentDemands.get(i).getDemand());
33             talentDemandRow.getCell(3).setCellValue(talentDemands.get(i).getAge());
34             talentDemandRow.getCell(4).setCellValue(talentDemands.get(i).getFkAcademicDegreeName());
35             talentDemandRow.getCell(5).setCellValue(talentDemands.get(i).getTechnicalTitles());
36             talentDemandRow.getCell(6).setCellValue(talentDemands.get(i).getProfession());
37             talentDemandRow.getCell(7).setCellValue(talentDemands.get(i).getFkTalentCategoryName());
38             talentDemandRow.getCell(8).setCellValue(talentDemands.get(i).getFkServiceFormName());
39             talentDemandRow.getCell(9).setCellValue(talentDemands.get(i).getProvide());
40             talentDemandRow.getCell(10).setCellValue(talentDemands.get(i).getOtherCases());
41             talentDemandRow.getCell(11).setCellValue(talentDemands.get(i).getFkIntentionToChooseName());
42         }
43     }

首先,我先说明我的需求:

 

Excel中,每个单元格都有可能会被计算,所以我们在填充数据的时候,要先知道数据的类型,然后将数据类型的类型转化一下,再用SetCellValue函数,将数值填充进去。

 

因为我用的是NPOI的方法,查了很多资料,发现目前NPOI不支持对图的捕捉和设置。所以,迫不得已,只能采用笨方法,那就是预先设置好足够的行数,例如1000行,然后将数据填充进去,将多的数据隐藏掉。

 

//这里有个for循环,循环获取dtDay的每个值,然后判断类型再填充进去
switch (dtDay.Columns[j].DataType.ToString())
                                {
                                    case "System.String"://字符串类型
                                        unionCell.SetCellValue(drValue);
                                        break;
                                    case "System.DateTime"://日期类型
                                        DateTime dateV;
                                        DateTime.TryParse(drValue, out dateV);
                                        unionCell.SetCellValue(dateV);

                                        break;
                                    case "System.Boolean"://布尔型
                                        bool boolV = false;
                                        bool.TryParse(drValue, out boolV);
                                        unionCell.SetCellValue(boolV);
                                        break;
                                    case "System.Int16"://整型
                                    case "System.Int32":
                                    case "System.Int64":
                                    case "System.Byte":
                                        int intV = 0;
                                        int.TryParse(drValue, out intV);
                                        unionCell.SetCellValue(intV);
                                        break;
                                    case "System.Decimal"://浮点型
                                    case "System.Double":
                                        double doubV = 0;
                                        double.TryParse(drValue, out doubV);
                                        unionCell.SetCellValue(doubV);
                                        break;
                                    case "System.DBNull"://空值处理
                                        unionCell.SetCellValue("");
                                        break;
                                    default:
                                        unionCell.SetCellValue("");
                                        break;
                                }

 

 

  1、分了6个sheet页,每页的数据都不一样,首先代码里要获得它们的数据,然后6个sheet页只能一个个填进去,没法批量操作。

图片 3

 

View Code

二、本次功能需求

// 格式化当前sheet,用于数据计算
UnionBook.SetForceFormulaRecalculation(true);

 

//隐藏多余行
                    for (int i = 5 + count * 100 + dtDay.Rows.Count; i < 77 + count * 100; i++)
                    {
                        IRow dataRowD = unionSheet.GetRow(i);//获取行
                        //将行的高度设为0,隐藏起来
                        dataRowD.Height = 0;                
                        dataRowD.ZeroHeight = true;
                        //sheet.RemoveRow(dataRowD);
                    }

 

图片 4图片 5

  2、如果直接代码创建Excel并画表格样式和数据,那么工程量将会很大,而且会导致代码很乱。我采用的方法是把模板保存到项目里,再通过路径获取到该模板文件,把其内容全部复制到新创建的Excel中,再往里填充数据。

 在做的过程中,发现饼图并不会随着插入的行而位置向下移。也就是说,图中饼图的位置是12行到27行,当我插入40行数据时,饼图的位置,还是在12行到27行。

  给了一个模板,里面有6个sheet页,每页里面都需要填充相应的数据。如图:

View Code

 

最后,有个需要注意的地方,在填充好数据后,准备写入Excel前,我们要先执行一下下面的语句,用来使模板中计算公式生效。

图片 6

我需要这个样子的模板。6到8行空着,是为了方便填充数据,其实只需要第6行这一行就好,当做模板复制。有多少行数据,我就会在sheet中插入多少行。

相关文章