首页 新闻 会员 周边

关于NPOI2.0操作EXCEL单元格格式的时候,会覆盖原本模板的单元格格式。为什么?如何解决?

0
悬赏园豆:50 [已解决问题] 解决于 2015-02-04 00:00

1.模板将各列的字体和单元格格式等都定义完成后。

2.利用NPOI2.0.1.DLL操作方法,读取模板→添加数据→增加单元格边框→另保存为。

问题出现了.

 1 private void NPOI_SetExcel(string filename, DataTable dt)
 2         {
 3             FileStream file = new FileStream(@"..\..\Template/" + filename + ".xls", FileMode.Open, FileAccess.Read);
 4             HSSFWorkbook hssfworkbook = new HSSFWorkbook(file);
 5             file.Close();
 6             ISheet sheet1 = null;
 7 
 8 
 9             #region 发料单
10             if (filename == "material issue report")
11             {
12 
13                 sheet1 = hssfworkbook.GetSheet("Sheet1");
14                 HSSFRow row = null;
15                 HSSFCell cell = null;
16                 //单元格边框样式
17                 HSSFCellStyle style = hssfworkbook.CreateCellStyle() as HSSFCellStyle;
18                 style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
19                 style.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;
20                 style.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;
21                 style.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;
22                 //单元格字体
23                 //HSSFFont font = hssfworkbook.CreateFont() as HSSFFont;
24                 //style.SetFont(font);
25                 //font.FontName = "宋体";
26                 //font.FontHeightInPoints = 8;
27                 //单元格格式
28                 //HSSFDataFormat format = (HSSFDataFormat)hssfworkbook.CreateDataFormat();
29                 //string[] arr = new string[16] { "0", "0", "0", "General", "General", "#,##0.00", "#,##0.00", "#,##0.00", "General", "0", "General", "yyyy-MM-dd", "0", "General", "#,##0.00", "General" };
30                 #region 填充数据
31                 for (int x = 0; x < dt.Rows.Count; x++)
32                 {
33                     if (sheet1.GetRow(x + 7) == null)
34                     {
35                         sheet1.CreateRow(x + 7);
36                     }
37                     for (int y = 0; y < dt.Columns.Count - 1; y++)
38                     {
39                         if (y == 0)
40                         {
41                             sheet1.GetRow(x + 7).CreateCell(y).SetCellFormula("row()-7");
42                         }
43                         else if (y == 1)
44                         {
45                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
46                         }
47                         else if (y == 2)
48                         {
49                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
50                         }
51                         else if (y == 9)
52                         {
53                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
54                         }
55                         else
56                         {
57                             switch (dt.Columns[y].DataType.ToString())
58                             {
59                                 case "System.String"://字符串类型
60                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(dt.Rows[x][y].ToString());
61                                     break;
62                                 case "System.DateTime"://日期类型
63                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(DateTime.Parse(dt.Rows[x][y].ToString()).ToString("yyyy-MM-dd"));
64                                     break;
65                                 case "System.Int16"://整型
66                                 case "System.Int32":
67                                 case "System.Int64":
68                                 case "System.Byte":
69                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
70                                     break;
71                                 case "System.Decimal"://浮点型
72                                 case "System.Double":
73                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(double.Parse(dt.Rows[x][y].ToString()));
74                                     break;
75                                 case "System.DBNull"://空值处理
76                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue("");
77                                     break;
78                                 default:
79                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue("");
80                                     break;
81                             }
82                         }
83                         row = sheet1.GetRow(x + 7) as HSSFRow;
84                         cell = row.GetCell(y) as HSSFCell;
85                         //cell.CellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
86                         //style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
87                         cell.CellStyle = style;//填充格式的时候,会将我模板定义好的格式替换掉,可是我并没有设置单元格格式,只是设置了边框。
88                     }
89                 }
90                 #endregion
91             }
92             #endregion
93             sheet1.ForceFormulaRecalculation = true;
94             FileStream file2 = new FileStream(@"c:\" + filename + "-" + FromDateTime.Text + "-" + ToDateTime.Text + ".xls", FileMode.Create, FileAccess.Write);
95             hssfworkbook.Write(file2);
96             file2.Close();
97         }
View Code

请问这个问题如何解决?

问题:在填充style的时候会将我模板的格式覆盖掉(如果我只是设置style的边框,在填充的时候会覆盖掉我模板的字体)这个问题如何解决?请给予勇于回答,并给与示例。

Setme的主页 Setme | 初学一级 | 园豆:123
提问于:2014-04-02 08:04
< >
分享
最佳答案
2

你那是cell.CellStyle=style;这种赋值操作,你为什么会觉得它应该是追加样式呢?
正确的做法是,先取出这个cell的样式,然后操作style对象,增加边框,然后赋值回去。

收获园豆:45
幻天芒 | 高人七级 |园豆:37175 | 2014-04-02 09:54

你好,很感谢你的回复。确实很有帮助,但是出现了第二个问题。请看代码和截图。

 1 sheet1 = hssfworkbook.GetSheet("Sheet1");
 2                 HSSFRow row = null;
 3                 HSSFCell cell = null;
 4                 //单元格边框样式
 5                 HSSFCellStyle style = hssfworkbook.CreateCellStyle() as HSSFCellStyle;
 6                 #region 填充数据
 7                 for (int x = 0; x < dt.Rows.Count; x++)
 8                 {
 9                     if (sheet1.GetRow(x + 7) == null)
10                     {
11                         sheet1.CreateRow(x + 7);
12                     }
13                     for (int y = 0; y < dt.Columns.Count - 1; y++)
14                     {
15                         if (y == 0)
16                         {
17                             sheet1.GetRow(x + 7).CreateCell(y).SetCellFormula("row()-7");
18                         }
19                         else if (y == 1)
20                         {
21                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
22                         }
23                         else if (y == 2)
24                         {
25                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
26                         }
27                         else if (y == 9)
28                         {
29                             sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
30                         }
31                         else
32                         {
33                             switch (dt.Columns[y].DataType.ToString())
34                             {
35                                 case "System.String"://字符串类型
36                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(dt.Rows[x][y].ToString());
37                                     break;
38                                 case "System.DateTime"://日期类型
39                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(DateTime.Parse(dt.Rows[x][y].ToString()).ToString("yyyy-MM-dd"));
40                                     break;
41                                 case "System.Int16"://整型
42                                 case "System.Int32":
43                                 case "System.Int64":
44                                 case "System.Byte":
45                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
46                                     break;
47                                 case "System.Decimal"://浮点型
48                                 case "System.Double":
49                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue(double.Parse(dt.Rows[x][y].ToString()));
50                                     break;
51                                 case "System.DBNull"://空值处理
52                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue("");
53                                     break;
54                                 default:
55                                     sheet1.GetRow(x + 7).CreateCell(y).SetCellValue("");
56                                     break;
57                             }
58                         }
59                         row = sheet1.GetRow(x + 7) as HSSFRow;
60                         cell = row.GetCell(y) as HSSFCell;
61                         style = cell.CellStyle as HSSFCellStyle;
62                         style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
63                         style.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;
64                         style.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;
65                         style.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;
66                         cell.CellStyle = style;
67                     }
68                 }
69             }
View Code

如图所示。它将所有行的单元格都加了边框。如何解决?我在上面也设定了X行和Y列的单元格,可是无效啊。

Setme | 园豆:123 (初学一级) | 2014-04-02 14:46

@Setme: 似乎是你的代码逻辑问题哦~

幻天芒 | 园豆:37175 (高人七级) | 2014-04-02 17:19

@幻天芒: 可以帮我看一下么? 难道步骤是:

1、创建各个单元格

2、设置单元格样式

3、填充数据

 

要三次嵌套for循环么?

Setme | 园豆:123 (初学一级) | 2014-04-02 17:21

@Setme: 我看你的代码好像是对所有单元格设置边框呢,检查下条件判断~

幻天芒 | 园豆:37175 (高人七级) | 2014-04-03 18:47

@幻天芒: 

style = cell.CellStyle as HSSFCellStyle; style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN; style.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN; style.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN; style.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN; cell.CellStyle = style;

现在的问题是,如果我将设置style格式的代码放在循环里,就会变成所有单元格都会有边框,如果放在循环外面就是正确的。

可是如果我放在循环外面,我该如何去进行style = cell.CellStyle as HSSFCellStyle;得到模板的单元格格式呢?好郁闷啊,我快被折腾死了

Setme | 园豆:123 (初学一级) | 2014-04-03 21:47

@Setme: 你的代码两个地方有问题:

1、sheet1.GetRow(x + 7).CreateCell(y).SetCellFormula("row()-7");

每次操作Cell,都是CreateCell,那么新创建的这个Cell肯定是没样式的,所以复制样式就没用了。(本身就是默认样式);

2、使用样式时,需要每次创建一个新的。

参考代码:

if (sheet1.GetRow(x + 7) == null)
                {
                    sheet1.CreateRow(x + 7);
                }
                for (int y = 0; y < dt.Columns.Count - 1; y++)
                {
                    ICell cell1 = sheet1.GetRow(x + 7).GetCell(y);
                    if (y == 0)
                    {
                        cell1.SetCellFormula("row()-7");
                    }
                    else if (y == 1)
                    {
                        cell1.SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
                    }
                    else if (y == 2)
                    {
                        cell1.SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
                    }
                    else if (y == 9)
                    {
                        cell1.SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
                    }
                    else
                    {
                        switch (dt.Columns[y].DataType.ToString())
                        {
                            case "System.String"://字符串类型
                                cell1.SetCellValue(dt.Rows[x][y].ToString());
                                break;

                            case "System.DateTime"://日期类型
                                cell1.SetCellValue(DateTime.Parse(dt.Rows[x][y].ToString()).ToString("yyyy-MM-dd"));
                                break;

                            case "System.Int16"://整型
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Byte":
                                cell1.SetCellValue(Int64.Parse(dt.Rows[x][y].ToString()));
                                break;

                            case "System.Decimal"://浮点型
                            case "System.Double":
                                cell1.SetCellValue(double.Parse(dt.Rows[x][y].ToString()));
                                break;

                            case "System.DBNull"://空值处理
                                cell1.SetCellValue("");
                                break;

                            default:
                                cell1.SetCellValue("");
                                break;
                        }
                    }
                    ICellStyle style = hssfworkbook.CreateCellStyle();//创建新样式
                    style.CloneStyleFrom(cell1.CellStyle);//复制原本的样式
                    style.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
                    style.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
                    style.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
                    style.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
                    cell1.CellStyle = style;

注意红色的代码。

幻天芒 | 园豆:37175 (高人七级) | 2014-04-04 01:06

@幻天芒: 你好,用style.CloneStyleFrom(cell1.CellStyle)这个方法确实可以继承原始格式,太有帮助了,谢谢你。

但是又出现了一个问题,那就是单元格格式。

例如:单元格row[0][0]格式是数字,单元格row[0][1]格式是日期,单元格row[0][2]格式是"#,##0.00".

现在的问题是,我用了style.CloneStyleFrom(cell1.CellStyle),导出excel后。

所有的单元格的格式都变成了"#,##0.00",他将所有单元格格式都替换成了最后一个,这又是为什么呢?如何解决啊?

Setme | 园豆:123 (初学一级) | 2014-04-04 01:39

@Setme: 你再检查下代码,我测试的时候没有遇到这个问题。

幻天芒 | 园豆:37175 (高人七级) | 2014-04-04 10:06

@幻天芒: 你好,天芒兄。我现在才理解你说的每次创建新单元格的时候要创建新的CellStyle.

但是我的数据有几千条。当我为每个单元格都创建新的cellstyle的时候会报4000异常(单元格样式不能超过4000个,感觉是作者故意限定的。不会要交钱后才能用吧?),你那里会报这个异常吗?

Setme | 园豆:123 (初学一级) | 2014-04-04 14:54

@Setme: 没测试这么大的数据,这个插件是开源的,应该不会是作者故意限制的,可能Excel有这个限制吧。我晚上测试下创建很多CellStyle,是否会出错。

幻天芒 | 园豆:37175 (高人七级) | 2014-04-04 15:57

@幻天芒: 好的,谢谢你啊

Setme | 园豆:123 (初学一级) | 2014-04-05 23:24

@Setme: 客气了~

幻天芒 | 园豆:37175 (高人七级) | 2014-04-07 19:15
其他回答(1)
1

0-0这问题还卡在啊

模板的用法不对

如果有要新生成的行和列,那么我们也要对新的行和列的样式进行设置,怎么设置样式那是你自己考虑的问题了

如果新生成的行和列是在原来的模板的固定的数据填充区域,并且超过了填充区域范围,样式也会被覆盖掉,因为你是相当于新生成数据填充区域

参考http://www.cnblogs.com/yzb305070/archive/2012/06/23/2483433.html

收获园豆:5
澜紫癜青 | 园豆:313 (菜鸟二级) | 2014-04-03 08:34
style = cell.CellStyle as HSSFCellStyle;

 style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;

style.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;

style.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;

style.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;

cell.CellStyle = style;

现在的问题是,如果我将设置style格式的代码放在循环里,就会变成所有单元格都会有边框,如果放在循环外面就是正确的。

可是如果我放在循环外面,我该如何去进行style = cell.CellStyle as HSSFCellStyle;得到模板的单元格格式呢?好郁闷啊,我快被折腾死了

支持(0) 反对(0) Setme | 园豆:123 (初学一级) | 2014-04-03 21:47
支持(0) 反对(0) Setme | 园豆:123 (初学一级) | 2014-04-03 21:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册