ListView中队数据的导出与DataGridView略有不同。而且由于WPF中不支持创建WookBook直接来写数据到Excel中,因而在处理要进行一些技术性处理。下面以我前段时间做的一个处理为例。下面是示例方法:
private void OutPutBill_Click(object sender,
RoutedEventArgs e)
{
//判断是否有数据
if (SignInList.ItemsSource ==
null) //SignInList是WPF中的ListView,即为数据源
{
MessageBox.Show("没有可供导出的数据");
return;
}
//创建数据导出文件对话框,以设置文件路径
SaveFileDialog saveFile = new SaveFileDialog() { Filter = "CSV
Files (*.csv)|*.csv|Excel Files
(*.xls)|*.xls|All files
(*.*)|*.*" };
saveFile.Title = "导出文件路径";
saveFile.FilterIndex = 2;
return
saveFile; StringBuilder strBuilder = new StringBuilder();
if (saveFile.ShowDialog() == true)
{
//获取文件格式
string strFormat =
saveFile.SafeFileName.Substring(saveFile.SafeFileName.IndexOf('.')
+ 1).ToUpper();
List<string> signLists = new
List<string>();
//将ListView的Header写入
if (1 == 1)
{
signLists.Clear();
//根据ListView的Header名称(ListVew中Header对应的Name)访问获取其文本
signLists.Add(Format(BillNO.Header.ToString(),
strFormat)); //调用公共方法进行字符转换
signLists.Add(Format(ResumeNO.Header.ToString(), strFormat));
signLists.Add(Format(ExamTypeName.Header.ToString(),
strFormat));
signLists.Add(Format(SignState.Header.ToString(),
strFormat));
signLists.Add(Format(SignInDate.Header.ToString(),
strFormat));
signLists.Add(Format(SignInTime.Header.ToString(),
strFormat));
//按行写入Header
BuilderStringOfRow(strBuilder, signLists, strFormat);
}
foreach (RecSignIN recSign in SignInList.Items)
{
signLists.Clear();
//根据记录对应的属性获取值写入
signLists.Add(Format(recSign.BillNO, strFormat));
signLists.Add(Format(recSign.ResumeNO, strFormat));
//signLists.Add(Format(recSign.ExamTypeID, strFormat));
signLists.Add(Format(recSign.ExamTypeName, strFormat));
signLists.Add(Format(recSign.SignState.ToString(),
strFormat));
signLists.Add(Format(recSign.SignInDate, strFormat));
signLists.Add(Format(recSign.SignInTime, strFormat));
//按行写入一条记录
BuilderStringOfRow(strBuilder, signLists, strFormat);
}
//数据写入文件
try
{
StreamWriter sw = new StreamWriter(saveFile.OpenFile());
if (strFormat == "XLS")
{
//Let us write the headers for the Excel XML
sw.WriteLine("<?xml version="1.0"
encoding="utf-8"?>");
sw.WriteLine("<?mso-application
progid="Excel.Sheet"?>");
sw.WriteLine("<Workbook
xmlns="urn:schemas-microsoft-com:office:spreadsheet">");
sw.WriteLine("<DocumentProperties
xmlns="urn:schemas-microsoft-com:office:office">");
sw.WriteLine("<Author>WFT</Author>");
sw.WriteLine("<Created>" +
DateTime.Now.ToLocalTime().ToLongDateString() +
"</Created>");
sw.WriteLine("<LastSaved>" +
DateTime.Now.ToLocalTime().ToLongDateString() +
"</LastSaved>");
sw.WriteLine("<Company>NPU
Ltd.,</Company>");
sw.WriteLine("<Version>12.00</Version>");
sw.WriteLine("</DocumentProperties>");
sw.WriteLine("<Worksheet ss:Name="Sheet1"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
>");
sw.WriteLine("<Table>");
}
sw.Write(strBuilder.ToString());
if (strFormat == "XLS")
{
sw.WriteLine("</Table>");
sw.WriteLine("</Worksheet>");
sw.WriteLine("</Workbook>");
}
sw.Close();
MessageBox.Show("数据已经成功导出!");
}
catch (Exception ex)
{
MessageBox.Show("数据导出失败,错误信息:" + ex.Message);
} }
}
其中调用的Format方法如下:
public string Format(string item, string strFormat)
{
switch (strFormat)
{
case "XLS":
return
String.Format("<Cell><Data
ss:Type="String">{0}</Data></Cell>",
item);
case "CSV":
return String.Format(""{0}"", item.Replace(""",
""""").Replace("n", "").Replace("r", ""));
}
return item;
}
其中调用的BuilderStringOfRow方法如下:
public void BuilderStringOfRow(StringBuilder
strBuilder, List<string> signLists,
string strFormat)
{
switch (strFormat)
{
case "XLS":
strBuilder.AppendLine("<Row>");
strBuilder.AppendLine(String.Join("rn",
signLists.ToArray()));
strBuilder.AppendLine("</Row>");
break;
case "CSV":
strBuilder.AppendLine(String.Join(",", signLists.ToArray()));
break;
}
}
本例中的技巧在于如何获取表头和表中数据。因为ListView不像DataGrid有ColumnHeader属性,因而刚开始绞尽脑汁也没想出怎么去获取。而且表中数据如果通过控件值去获取很麻烦。这就是我在本例中技巧性处理的精华了,请看:
<local:UserEditListView x:Name="SignInList"
Style="{DynamicResource
listDetailStyle}" //数据源SignInList
Background="{x:Null}"
Margin="0,0,0,0"
BorderBrush="{x:Null}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
SelectionMode="Single"
FontSize="16"
FontFamily="SimSun"
Height="Auto"
>
<ListView.View>
<GridView AllowsColumnReorder="False"
>
<local:SortListViewColumn Header="单据编号" Width="160"
SortProperty="BillNO"
x:Name="BillNO" CellTemplate="{StaticResource billno}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<local:SortListViewColumn Header="简历编号" Width="160"
SortProperty="ResumeNO"
x:Name="ResumeNO" CellTemplate="{StaticResource resumeno}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<local:SortListViewColumn Header="应聘考试类型"
Width="160" SortProperty="ExamTypeName"
x:Name="ExamTypeName" CellTemplate="{StaticResource exametypename}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<local:SortListViewColumn Header="签到情况" Width="100"
SortProperty="SignState" x:Name="SignState" CellTemplate="{StaticResource signstate}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<local:SortListViewColumn Header="签到日期" Width="160"
SortProperty="SignInDate" x:Name="SignInDate" CellTemplate="{StaticResource signindate}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<local:SortListViewColumn Header="签到时间" Width="150"
SortProperty="SignInTime" x:Name="SignInTime" CellTemplate="{StaticResource signintime}"
HeaderContainerStyle="{DynamicResource
listHeaderStyle}"/>
<GridViewColumn Width="200"
CellTemplate="{StaticResource empty}"
HeaderContainerStyle="{DynamicResource listHeaderStyle}"
/>
</GridView>
</ListView.View>
</local:UserEditListView>
仔细看上面的程序,你会发现我对每一个SortListViewColumn
都进行了命名,这就是关键所在。一般我们使用ListView很少会对其列(WPF中)进行命名,因为我们会觉得用不着,的确,平常我也不对其命名。不过正是因为这,我们忽略这个属性的作用。在该例中,它给我们省下了很大力气。之后我们就可以通过属性名获得该列的Header及数据值。
是不是很有趣,如果你觉得好就请拍拍手!!!