【问题标题】:Export ListView Items to Excel (AutoWidth Columns, Headers in First Row, Hide Certain Rows)将 ListView 项目导出到 Excel(AutoWidth 列、第一行中的标题、隐藏某些行)
【发布时间】:2014-06-17 00:36:39
【问题描述】:

我有一个小型应用程序,我正在尝试添加增强功能,以便在单击按钮时将表单列表视图中的所有数据导出到 Excel 工作表。经过大量搜索,我在 DaniWeb 找到了 this 解决方案,它做得很好,但我正在尝试扩展它。

Excel.Application app = new Excel.Application();
app.Visible = true;
Excel.Workbook wb = app.Workbooks.Add(1);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1];
int i = 1;
int i2 = 1;
foreach (ListViewItem lvi in lvData.Items)
{
    i = 1;
    foreach (ListViewItem.ListViewSubItem lvs in lvi.SubItems)
    {
        ws.Cells[i2, i] = lvs.Text;
        i++;
    }
    i2++;
}

Excel.Range rng = null;
rng = Excel.Range("A1:Z" + lvData.Items.Count); // Error: Microsoft.Office.InterOp.Excel.Range is a 'type', which is not valid in the given context.
rng.Columns.AutoFit();

// RANGE COPY IN WORD INTEROP
// oWord.ActiveDocument.Sections[cnt].Range.Copy();
// Set focus to the New Word Doc instance
// oNewWord.Activate();
// Paste copied range to New Word Doc
// oNewWord.ActiveDocument.Range(0, 0).Paste();

MessageBox.Show("Export Completed", "Export to Excel", MessageBoxButtons.OK, MessageBoxIcon.Information);

我也想:

  1. 自动将所有单元格宽度设置为数据的宽度。
  2. 将 ListView 列标题的值放入 Excel 的第一行。
  3. 我的列表视图中总共有 26 列,但实际上我只需要将大约 10 列导出给用户(我在前端的用户视图中隐藏了其中的许多列,然后在后端将它们用于其他功能处理)。

我仍在寻找,但尚未找到任何解决方案。我有从 Excel/Access 到 .Txt 的经验,但从未做过 ListView 到 Excel。有人对我如何完成上述工作有想法吗?

谢谢!

编辑:

使用 Derek 的建议,现在所有列的宽度在处理结束时自动设置为列中最大单元格内容的大小。根据 Miles 的建议,我做了一些尝试,并设法拼凑了一些代码,将 ColumnHeader 值插入到 Excel 的第一个行中。

现在只是想弄清楚如何隐藏某些不需要的列或不导出特定的列。

                // http://www.daniweb.com/software-development/csharp/threads/192620/listview-to-excel
                Excel.Application app = new Excel.Application();
                app.Visible = true;
                Excel.Workbook wb = app.Workbooks.Add(1);
                Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1];
                int i = 1;
                int i2 = 2;
                int x = 1;
                int x2 = 1;
                int j = 0;
                int colNum = lvData.Columns.Count;

                // Set first ROW as Column Headers Text
                foreach (ColumnHeader ch in lvData.Columns)
                {
                        ws.Cells[x2, x] = ch.Text;
                        x++;
                }

                foreach (ListViewItem lvi in lvData.Items)
                {
                    i = 1;
                    foreach (ListViewItem.ListViewSubItem lvs in lvi.SubItems)
                    {
                        ws.Cells[i2, i] = lvs.Text;
                        i++;
                    }
                    i2++;
                }

                // AutoSet Cell Widths to Content Size
                ws.Cells.Select();
                ws.Cells.EntireColumn.AutoFit();

                MessageBox.Show("Export Completed", "Export to Excel", MessageBoxButtons.OK, MessageBoxIcon.Information);

EDIT2

我在另一个程序中使用流写入器做了一些事情,我在其中查看了特定的索引。如果它不是最后一个索引(列),我将一个值附加到一个长字符串的末尾。如果它是最后一个值(列),我将整个字符串写入文件。通过这种方式,我可以将值从 ListView 导出到 (!) 分隔的 .Txt 文件。我在这里为#3 尝试类似的东西,但还没有:

                // indices is used to designate which columns in the ListView we want
                var indices = new int[] { 0, 1, 2, 8, 9, 15, 19, 22, 23, 24, 25 };
                foreach (ListViewItem lvi in lvData.Items)
                {
                    i = 1;
                    foreach (int id in indices)
                    {
                        ws.Cells[i2, i] = lvi.SubItems.ToString();
                        i++;
                    }

                    //foreach (ListViewItem.ListViewSubItem lvs in lvi.SubItems)
                    //{
                    //    ws.Cells[i2, i] = lvs.Text;
                    //    i++;
                    //}
                    i2++;
                }

【问题讨论】:

    标签: c# .net listview export-to-excel excel-interop


    【解决方案1】:

    对于第一部分,看起来你可以这样做:

        ws.Cells[i, j].ColumnWidth = lvs.Text.Length;
    

    查看此页面:http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range_members.aspx

    对于第二部分和第三部分,我有点困惑问题是什么。您不能只遍历您的 ListView 并将这些列值写入第一行吗?

    【讨论】:

    • 感谢迈尔斯的回复。我使用了代码并将列标题插入到第一个 Excel 行中。 Derek 实际上对 Column Widths 有更好的建议(在最后而不是在每次插入期间修改全部)。仍在处理#3。
    【解决方案2】:

    对于自动调整:

      //make all columns autofit
      workSheet.Cells.Select();
      workSheet.Cells.EntireColumn.AutoFit();
    

    对于列标题(使用 Linq):

    (可能需要调整索引,但我认为不需要)

      foreach ( ColumnHeader column in lv.Columns.OfType<ColumnHeader>() )
      {
         workSheet.Cells[ 1, column.Index + 1 ] = column.Name;
      }
    

    那么您可能需要调整下一段代码。我会遍历 ListViewItems 并单独设置单元格。

    您可以处理 listviewitems 的循环并只执行您想要的那些。例如前十。我只会做 worksheet.Cells[ rowIndex, columnIndex ] = ... 来设置所有的值。

    其中一个技巧。
    SubItems 实际上从第二列开始。

    listViewItem.Name 为您提供第一列

    所以:

    在 listViewItems 循环中...

    worksheet.Cells[ rowIndex, 1 ] = listViewItem.Name;
    j = 2;
    
    foreach (ListViewItem.ListViewSubItem lvs in lvi.SubItems)
    {
       ws.Cells[rowIndex, j] = lvs.Text;
       j++;
     }
     j++;
    

    【讨论】:

    • 感谢德里克的回复。您对列宽的建议非常有效:) 我得到了标题 2,现在我只是想弄清楚我原来的帖子的 #3。您可能在循环中的特定值而不是所有列上都是正确的,但我将不得不玩弄它一段时间,看看我是否可以让它工作。
    • 我不确定这是否可行。我实际上并没有得到确切的前 10 个。我实际上是在尝试检索以下列:{ 1, 2, 3, 9, 10, 16 20, 23, 24 25, 26 }
    【解决方案3】:

    兄弟,答案已经在您的代码中。不知道你有没有注意到。您制作了一个整数数组,现在使用它。喜欢:

                var indices = new int[] { 0, 1, 2, 8, 9, 15, 19, 22, 23, 24, 25 };
    
                foreach (ListViewItem lvi in lvData.Items)
                {
                    i = 1;
                    int bol = lvi.SubItems.Count;
    
                    foreach (int id in indices)
                    { 
                        if (bol > 0)
                        {
                           ws.Cells[i2, i] = lvi.SubItems[id].Text;
                           i++;
                           bol--;
                        }
                    }
                    i2++;
                }
    

    对我来说,这是最简单的方法。但是,如果您想要更漂亮的东西,那么,运气!我向你保证它有效!

    PD:如果我写的是为了防止错误,请随意做其他事情。但这样就可以了,相信我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 2015-05-03
      • 1970-01-01
      相关资源
      最近更新 更多