使用OleDb.OleDbConnection将xlsx转换为CSV时丢失数据

时间:2018-11-06 09:55:24

标签: .net oledbconnection

我写了一个脚本将XLSX文件转换为CSV。

这很好用,但是现在我得到了一个有趣的错误,具体取决于xlsx中的数据。

这是我到目前为止发现的:

如果xlsx中的数据看起来像这样:

col#ID (1)50690

(2)50844

(3)ABC

(4)50899

(5)123ABCD

(6)ABCDE

(7)123456

CSV文件将不包含(3),(5),(6)

中的数据

如果xlsx中的数据看起来像这样:

col#ID (1)ABC

(2)50844

(3)ABC

(4)50899

(5)123ABCD

(6)ABCDE

(7)123456

CSV文件将包含所有数据。

那为什么呢,我需要在第一列中有一个字符串才能正常工作。 如何告诉脚本始终使用STRING作为数据类型,而不是首次出现的数据类型。

Public Sub ConvertXLS2CSV(ByVal fullPathSource As String, ByVal fullPathTarget As String, ByVal filename As String)
        Dim logger = LoggerFactory.CreateLogger(Me, MethodBase.GetCurrentMethod())
        logger.BeginMethod(New List(Of Object)({fullPathSource, fullPathTarget, filename}))

        'The data will be read with header row by default. fileHasHeader can be YES/NO
        Dim cDelimiter As Char = System.Convert.ToChar(CCC_GetConfigParm("Custom\OdBSystems\CSVDelimiter")) 'Default: "~"c Delimiter for the new CSV File
        Const fileHasHeader As String = "YES"
        Dim sSheetName As String = String.Empty

        'Build ConnectionString
        Dim sConnection As String =
String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR={1};IMEX=1""", fullPathSource, fileHasHeader)

        Try
            Using oleExcelConnection As New OleDb.OleDbConnection(sConnection)
                oleExcelConnection.Open()
                Using dtTablesList = oleExcelConnection.GetSchema("Tables")

                    If dtTablesList.Rows.Count > 0 Then
                        sSheetName = dtTablesList.Rows(0)("TABLE_NAME").ToString
                    End If
                    ' Check if the data sheet has a worksheet(table)
                    If sSheetName <> "" Then

                        Dim whereClauseXLSX As String = String.Empty
                        whereClauseXLSX = "SELECT * FROM [" & sSheetName & "]"

                        'Build Command to execute
                        Dim oleExcelCommand As OleDb.OleDbCommand = oleExcelConnection.CreateCommand()
                        oleExcelCommand.CommandText = whereClauseXLSX
                        oleExcelCommand.CommandType = CommandType.Text

                        'Initiate Adapter to execute command
                        Dim da As New OleDb.OleDbDataAdapter(oleExcelCommand)
                        Dim ds As New DataSet()

                        'Poupulate dataset with executed result
                        da.Fill(ds, sSheetName)

                        'Form string builder to export as CSV File
                        Dim dt As DataTable = ds.Tables(sSheetName)
                        Dim sb As New StringBuilder()

                        'Export ColumnNames
                        Dim columnNames As IEnumerable(Of String) = dt.Columns.Cast(Of DataColumn)().[Select](Function(column) column.ColumnName)
                        sb.AppendLine(String.Join(cDelimiter, columnNames))


                'Export Rows
                        For Each row As DataRow In dt.Rows.Cast(Of DataRow).ToList

                            Dim fields As IEnumerable(Of String) = row.ItemArray.[Select](Function(field) field.ToString())
                            Dim newline As String = String.Join(cDelimiter, fields).Replace(vbCr, "").Replace(vbLf, "")
                            Dim newlineWithoutDelimiter As String = newline.Replace(cDelimiter, "")

                            If Not String.IsNullOrWhiteSpace(newlineWithoutDelimiter) Then
                                sb.AppendLine(newline)
                            End If

                        Next

            'DEBUG stuff                
            Dim test As StringBuilder = New StringBuilder
                        test.Appendline(dt.Rows(dt.Rows.Count - 1)(13).toString)
                        test.Appendline(dt.Rows(dt.Rows.Count - 2)(13).toString)
                        test.Appendline(dt.Rows(dt.Rows.Count - 3)(13).toString)
                        test.Appendline(dt.Rows(dt.Rows.Count - 4)(13).toString)
                        'Throw New ViException(test.ToString)

                        File.WriteAllText(String.Format("{0}.csv", fullPathTarget), sb.ToString(), Text.Encoding.UTF8)

                    End If
                End Using
                'End using will close all open connections
            End Using
            'End using will close all open connections

        Catch ex As Exception
            Throw New ViException(String.Format("Error while reading XLSX-File: Exception: {0}", ex.Message))
        End Try
    End Sub

谢谢。

最好的问候, DonLedger

0 个答案:

没有答案