将列表视图项目导出到 Excel(自动加宽列、第一行中的标题、隐藏某些行)

本文关键字:一行 隐藏 标题 项目 视图 列表 Excel | 更新日期: 2023-09-27 17:56:06

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

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. 将列表视图列标题的值放入Excel的第一行。
  3. 我的列表视图中总共有 26 列,但实际上我只需要将大约 10 列导出给用户(我在前端的用户视图中隐藏了其中的许多列,然后在后端使用它们进行其他功能处理)。

我还在寻找,但还没有找到任何解决方案。我有从 Excel/Access 到 .Txt和同样,但从未做过ListView to Excel。有人对我如何完成上述工作有想法吗?

谢谢!

编辑:

使用 Derek 的建议,所有列现在都会在处理结束时自动将其宽度设置为列中最大单元格内容的大小。使用迈尔斯的建议,我做了一些玩弄,并设法拼凑了一些代码,将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);

编辑2

我在另一个程序中使用流编写器做了一些事情,在那里我查看了特定的索引。如果它不是最后一个标记(列),我将一个值附加到长字符串的末尾。如果它是最后一个值(列),我将整个字符串写到文件中。通过这种方式,我可以将值从列表视图导出到 (!) 分隔的 .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++;
                }

将列表视图项目导出到 Excel(自动加宽列、第一行中的标题、隐藏某些行)

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

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

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

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

对于自动调整:

  //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;
  }

然后,您可能需要调整代码的下一部分。 我会遍历列表视图项并单独设置单元格。

您可以处理循环浏览列表视图项并仅执行所需的项。 例如,前十个。 我只会做工作表。单元格[ 行索引, 列索引 ] = ...以设置所有值。

诀窍之一。
子项实际上从第二列开始。

listViewItem.Name 为您提供第一列

所以:

在循环遍历列表视图项...

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

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

            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:如果我写的是为了防止错误,请随意做其他事情。但以这种方式它起作用,相信我。