背景:我从数据库中填充了大量asp.net c#GridViews和ListViews,随后用户可以将它们导出到Excel。我想导出为原生Excel(而不是HTML)。我不能使用办公自动化,我正在使用JET工作正常。我无法控制用户的机器。
问题:在进行导出时,你必须告诉Jet每个字段的类型,在我的例子中是“text”(varchar)或“numeric”(double)。不同之处在于,如果导出数字列,则用户可以对Excel中的数据求和,其中字符串与前导撇号一起导出,因此在算术中没有太大用处。
目前我解析Grid / ListView的第一个数据行,检查每个值是数字还是文本,并相应地为列指定类型。这是有效的,除了我在第一列中看起来像数字但实际上是文本字符串的东西。我不想解析每一行,以确保我有正确的数据类型,因为其中一些导出非常大。
当我从数据库加载Grid / ListView时,数据库肯定知道每个字段的类型。所以我的问题是......如何提取Grid / ListView项后面的数据库项的类型?我可以明确地将它编码为项目的属性,但这是我已经拥有的重复信息,只要我能找到它。
我知道我有一个DataTable,然后我可以从中获取底层类型,但大多数情况下我没有表格,只有Grid / ListView。
- (编辑) 请注意,如果您尝试将空字符串插入可以为空的数字列,则Jet将抛出。执行此操作的方法是从insert语句中省略该列名,或输出零。
答案 0 :(得分:0)
我认为您尝试做的是在绑定之后找出DataSource
或GridView
的基础ListView
?
如果是这样,那是不可能的,因为一旦绑定,控件就不会真正跟踪DataSource
。它们主要用于填充列,模板等,然后只维护这些项目。
我可以提供的唯一建议是将DataSource
存储在另一个位置,以便您以后可以访问它,然后使用它来发现用于每列的基础数据类型。如果需要,您可以将其存储在Session
或ViewState
中,但这会增加开销。另一种选择是在绑定之前弄清楚数据类型,然后将它们存储在隐藏字段中,使用某种格式,稍后可以使用它来复制正在执行的操作。
例如(不好的例子但是给你一个想法)在隐藏字段中存储以下数据:
yourHiddenField.Text = "0,1|1,1|2,0|3,1|etc...";
// format "columnindex,fieldtype(0=double,1=string)" with a pipe delimiter.
不漂亮,但说明了我的基本想法。
答案 1 :(得分:0)
据我所知,答案是“你不能”。我的数据源只返回字符串,因此您无法有效地解析任何自动创建的DataTable列类型。
我做的是 ......
我可以通过查看网格/列表的第一行来“嗅探”大多数列类型。仅当第一列数据为空(这不会告诉您任何内容),或者第一列含有数字但列数据是例如字母数字时,此操作才会失败。
因此,对于我知道存在问题的那些列,或者测试显示存在问题的那些列,我使用自定义属性来注释那些特定的Grid或ListView项目,该属性强制将项目导出为文本或数字。我默认使用文本,所以在实践中我大多只需要注释那些我特意想要呈现为数字的条目。例外是一些以前导零开头的ID号,我想以这种方式呈现,因此明确地作为文本。
我有一个DataTable(例如图表),我不能做嗅探技巧(见上文)或注释技巧(同上),然后我将列类型的地图传递给我的导出代码。
总之,在某些情况下,我不得不在Grid / ListView模板字段或字段映射中重复列类型定义。无法赢得所有人。它确实有效。