【问题标题】:Looking to export datagridview希望导出数据网格视图
【发布时间】:2013-12-30 22:13:18
【问题描述】:

我有一个滚动的 datagridview 动态改变它的列数和行数。我正在寻找一种在用户单击按钮时导出数据网格视图的方法。我希望它导出为无法编辑的东西(所以不是 excel 文件)。我尝试使用 iTextSharp 导出为 pdf,但似乎无法提出适合它的动态变化循环。此外,我还没有找到任何使用 iTextSharp 的示例代码,其中还包括导出行标题和列标题。我还在微软论坛上尝试了一种解决方案(目前我似乎找不到),该解决方案利用 Excel 的附加功能在将 datagridview 内容导出到 PDF 后写入 PDF。我遇到的问题是它创建了许多页面的方式,并且仍然显示已从 datagridveiw 隐藏或删除的行。知道如何完成这一壮举吗?

我将包含两张图片来展示 datagridview 动态填充和变化的方式

最多可以有 66 行和 12 列(不包括行或列标题)

【问题讨论】:

  • 如果底层数据源是DataTable,您可以通过myDataTable.WriteXml(nameOfFile)myDataTable.ReadXml(nameOfFile) 读取/写入XML。
  • 我从作为程序资源的 excel 文件中读取数据,因此我没有 DataTable 数据源。如何将其设置为数据表并使用 datagridview 中的数据填充它?
  • 我假设它需要某种循环,因为我的 datagridview 的大小发生了变化。

标签: vb.net excel datagridview export


【解决方案1】:

您可以使用EPPlus 创建一个受密码保护(锁定)的可以读取但不能编辑的excel 文件。我可以告诉你如何从这样的情况开始:

并获得这样的受保护文件:


首先,您必须下载 EPPlus Library 并将其包含在您的项目中。不要忘记查看伟大的EPPlusSamples Project

然后您需要一种方法来提取您的 DataGridView VISIBLE 数据(您不希望导出不可见的列)。我使用二维数组完成了它。这个函数接受一个DataGridView 参数并返回一个二维数组:

Function GetDataGridView2DArray(ByVal dataGridView As DataGridView) As String(,)
    'Save list of visible columns
    Dim nrVisibleColumns = (From c As DataGridViewColumn In DataGridView1.Columns
               Where c.Visible
               Select c).ToList()

    'create 2d-array to store values, dimensions given by number of rows and visible columns
    Dim dgvArray(nrVisibleColumns.Count, DataGridView1.Rows.Count) As String

    'create the first row with Column Headers text
    For Each col As DataGridViewColumn In nrVisibleColumns
        dgvArray(col.Index + 1, 0) = col.HeaderText
    Next

    'create Rows, including Row Header text
    For Each row As DataGridViewRow In DataGridView1.Rows
        Dim rowNumber = row.Index + 1
        dgvArray(0, rowNumber) = DataGridView1.Rows(row.Index).HeaderCell.Value 'save rowheader cell value 

        For Each col As DataGridViewColumn In nrVisibleColumns
            dgvArray(col.Index + 1, rowNumber) = DataGridView1(col.Index, row.Index).Value
        Next
    Next

    Return dgvArray
End Function

现在您已经有了数组,您可以创建一个 Excel 文件 并用数据填充它。另外,在保存之前,我们会用密码锁定它以防止用户编辑。

Private Sub CreateXls()
    Dim fi = New FileInfo("C:\temp\output.xlsx")
    Dim package As New ExcelPackage()

    Dim ws = package.Workbook.Worksheets.Add("Dgv Output") 'create sheet

    'get array of datagridview data
    Dim dataArray = GetDataGridView2DArray(DataGridView1)

    'loop my 2d array and fill my excel file
    For iColumn As Integer = dataArray.GetLowerBound(0) To dataArray.GetUpperBound(0)
        For iRow As Integer = dataArray.GetLowerBound(1) To dataArray.GetUpperBound(1)
            ws.Cells(iRow + 1, iColumn + 1).Value = dataArray(iColumn, iRow)
            ws.Cells(iRow + 1, iColumn + 1).Style.Locked = True 'lock the cell
        Next 
    Next

    ws.Cells.AutoFitColumns() 'resize columns to fit
    ws.Protection.AllowFormatColumns = True 'let user resize columns if he wants
    ws.Protection.SetPassword("1") 'protect the sheet from editing

    package.SaveAs(fi) 'save file
End Sub

现在您应该可以一键轻松导出动态DataGridView了。

【讨论】:

  • 如果我们已经使用另存为命令(因为 excel 支持另存为 PDF 格式)使用相同的方法将数据导出到 excel 中,我们不能只将数据保存为 pdf,但稍作调整?
  • @CaffeineCoder 您可以从刚刚创建的 excel 文件开始。使用 Interop.Excel,look here PDF 的主要问题是你永远不知道你会得到什么样的布局......尤其是动态行/列,你可能会得到可怕的结果,比如半空页面、只有 1 行的页面或只有 2 列的页面等。Excel 使最终用户能够以他想要的方式以他想要的格式打印文件。 (顺便说一下,您的问题被标记为 Excel)。
  • 我有一个完全不同的按钮,它可以打印 datagridview,但是它可以与 datagridview 的动态变化性质一起工作(使用 datagridview 打印机类),所以这就是我寻找纯粹的方法的原因的出口。打印不是问题,但我希望图表看起来不错
  • @CaffeineCoder 我的答案提供了您想要的一切。导出datagridview,包括行/列标题,排除不可见列,防止编辑。然后您可以尝试添加互操作代码以获取 excel 文件,将其保存为 PDF 并删除以前创建的 excel 文件。我想这一切都可以为你做,祝你好运
  • 你是对的。我将使用您提供的方法来查看是否可以完成保存到 pdf 的方法。如果我能得到想要的结果,你一定会得到答案
【解决方案2】:

这是我的编码测试并且输出是完美的:

    Dim ExcelApp As Object, ExcelBook As Object
    Dim ExcelSheet As Object
    Dim i As Integer
    Dim j As Integer

    'create object of excel
    ExcelApp = CreateObject("Excel.Application")
    ExcelBook = ExcelApp.WorkBooks.Add
    ExcelSheet = ExcelBook.WorkSheets(1)

    With ExcelSheet
        For Each col As DataGridViewColumn In Me.DataGridView1.Columns
            ExcelSheet.Cells(1, col.Index + 1) = col.HeaderText.ToString
            For i = 1 To Me.DataGridView1.RowCount
                ExcelSheet.cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells("First Column Name").Value
                For j = 1 To DataGridView1.Columns.Count - 1
                    ExcelSheet.cells(i + 1, j + 1) = DataGridView1.Rows(i - 1).Cells(j).Value
                Next
            Next
        Next
    End With
    ExcelApp.Visible = True
    ExcelSheet = Nothing
    ExcelBook = Nothing
    ExcelApp = Nothing

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    相关资源
    最近更新 更多