vb.netdatagridviewexport-to-text

Export DataGridView to text file keeping columns lined up


I am working on project for school, using VB, I am working in Visual Studio 2017. I have a DataGridView which I need to export to a Text File.

I could use some help with an export feature from VB to a Text file. Here is the code I am using:

Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
        Dim numCols As Integer = dgvApplianceList.ColumnCount
        Dim numRows As Integer = dgvApplianceList.RowCount - 1
        Dim strDestinationFile As String = "exportappliance.txt"
        Dim tw As TextWriter = New StreamWriter(strDestinationFile)

        'writing the header
        For count As Integer = 0 To numCols - 1
            tw.Write(dgvApplianceList.Columns(count).HeaderText)
            If (count <> numCols - 1) Then
                tw.Write(vbTab)
            End If
        Next
        tw.WriteLine()

        For count As Integer = 0 To numRows - 1
            For count2 As Integer = 0 To numCols - 1
                tw.Write(dgvApplianceList.Rows(count).Cells(count2).Value)
                If (count2 <> numCols) Then
                    tw.Write(vbTab)
                End If
            Next
            tw.WriteLine()
        Next
        tw.Close()
    End Sub

Current Export results


Solution

  • Since you are writing to a “text” file, one way to line up text properly can be accomplished using spaces as others have suggested. This would require that you have a “defined” column “width” for each column. Using your picture as an example, column 0 (zero) would be “Appliance Type” and we could give that column a max “width” of… say twenty five (25) characters wide. Column 2 “kwh” could be set with a maximum column width of 15 and so on for each column.

    With the “column widths” established, it should be a simple matter of adding X number of spaces needed to fill the string to the columns width. Example, to make sure column 2 lines up with the next column 2, each column 1 string MUST be all the same length. By filling each column 1 string with spaces to “fill” the string to column 1’s length, will ensure column 2’s text will line up correctly. Obviously, the same logic applies to subsequent columns.

    The GetBufferedString method (below) demonstrates one way to buffer the strings to a specified column width. The method takes a string originalString, an int maxLength and a justification type. The method will return a string of length maxLength such that, if the justification type is LEFT, the method will fill the given string with spaces at the end. If the justification type is RIGHT, the method will return a string of maxLength such that spaces are added to the front of the string. Finally, if the justification type is CENTER, then the method will return a string with half the spaces in front of the string and the other half at the end. If the given string’s length is greater than maxLength, then the returned string will be a maxLength truncation of the given string.

    This should enable you to set each columns justification type independently. The code below simply sets each rows justification type to right.

    This is an example and I hope it helps, however there is no error checking for a possible mismatch on the number of actual columns in the grid and the number of column widths.

    Some global variables… an integer array columnLengths is used to hold each columns width… also an enumeration for the justification type; RIGHT, LEFT, CENTER.

    Dim columnLengths(6) As Integer
    
    Enum JustifyType
      LEFT
      RIGHT
      CENTER
    End Enum
    

    Set each columns width…

    Private Sub FillColumnLength()
      columnLengths(0) = 25
      columnLengths(1) = 12
      columnLengths(2) = 12
      columnLengths(3) = 12
      columnLengths(4) = 12
      columnLengths(5) = 12
    End Sub
    

    An updated save button click event to use the GetBufferedString method.

    Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
      Dim numCols As Integer = dgvApplianceList.ColumnCount
      Dim numRows As Integer = dgvApplianceList.RowCount - 1
      Dim strDestinationFile As String = "D:\Test\exportappliance.txt"
      Dim tw As TextWriter = New StreamWriter(strDestinationFile)
      Dim textToOutput = ""
      For count As Integer = 0 To numCols - 1
        textToOutput = GetBufferedString(dgvApplianceList.Columns(count).HeaderText, columnLengths(count), JustifyType.CENTER)
        tw.Write(textToOutput)
      Next
      tw.WriteLine()
      For count As Integer = 0 To numRows - 1
        For count2 As Integer = 0 To numCols - 1
          textToOutput = GetBufferedString(dgvApplianceList.Rows(count).Cells(count2).Value, columnLengths(count2), JustifyType.RIGHT)
          tw.Write(textToOutput)
        Next
        tw.WriteLine()
      Next
      tw.Close()
    End Sub
    

    Finally, the GetBufferedString method.

    Private Function GetBufferedString(originalString As String, maxLength As Int16, justifyType As JustifyType) As String
      If (originalString.Length < maxLength) Then
        Dim bufString = Space(maxLength - originalString.Length)
        Select Case justifyType
          Case JustifyType.LEFT
            Return originalString + bufString
          Case JustifyType.RIGHT
            Return bufString + originalString
          Case JustifyType.CENTER
            Dim halfString = bufString.Substring(bufString.Length / 2)
            originalString = halfString + originalString
            bufString = Space(maxLength - originalString.Length)
            Return originalString + bufString
          Case Else
            Return ""
        End Select
      Else
        Return originalString.Substring(0, maxLength)
      End If
    End Function
    

    Hope this helps.