从 Excel 读取 - 以不同的列顺序写入 CSV
Read from Excel - write to CSV in different column order
我需要了解是否有可能在 VB.NET 内读取 Excel 文件的列并以不同的顺序将它们写入 CSV 文件。
实际中,我们发送的Excel文件有6栏:“金额”、“分公司”、“库存”、“方案”、“数量”、“类型”。公司管理系统接受具有不同顺序列的文本文件:“分支”、“库存”、“金额”、“数量”、“类型”、“建议”。这对我来说是个问题,因为当我去转换它时,我的 ERP无法识别该列位于不同的位置。
我到达了具体问题,我希望有可能阅读这些列并通过脚本使它们能够根据我决定的位置来定位它们。
我尝试使用此代码导入并转换为 txt,但我需要另一个脚本:
Imports System.IO
Imports ExcelDataReader
Imports System.Text
Public Class Form1
Dim tables As DataTableCollection
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xls)|*.xls|(*.xls)|*.xlsx"}
If ofd.ShowDialog() = DialogResult.OK Then
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim result As DataSet = reader.AsDataSet(New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}})
tables = result.Tables
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Using
End Using
End If
End Using
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
Dim dt As DataTable = tables(cboSheet.SelectedItem.ToString())
dgProposte.DataSource = dt
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim writer As TextWriter = New StreamWriter("C:\Users\antonio\Desktop\Prova.txt")
For i As Integer = 0 To dgProposte.Rows.Count - 2 Step +1
For j As Integer = 0 To dgProposte.Columns.Count - 1 Step +1
writer.Write(vbTab & dgProposte.Rows(i).Cells(j).Value.ToString() & vbTab & "")
Next
writer.WriteLine("")
Next
writer.Close()
MessageBox.Show("Dati Esportati")
End Sub
为什么不映射数据的 DTO table?
Public Class MioDto
Property campoUno As String
Property campoDue As String
'...ecc
End Class
然后你可以在一个cicle中填充一个dto...
Dim a As New MioDto() With {.campoUno="...", campoDue="..."}
或者如果您愿意,可以使用
https://github.com/AutoMapper/AutoMapper
填写 Dto class 后,您可以使用它生成包含您或首选订单的 txt。
您通过导入 Excel sheet(s) 得到的表设置了它们的列名,您可以按列名索引该列。
所以,稍微调整一下,找出一些方法:
Imports System.IO
Imports ExcelDataReader
Public Class Form1
Dim tables As DataTableCollection
Private Sub WriteToCsv(tableName As String, filename As String)
Dim columnWriteOrder = {"branch", "stock", "amount", "quantity", "type", "proposal"}
Using writer As TextWriter = New StreamWriter(filename)
Dim tbl = tables(tableName)
For i As Integer = 0 To dgProposte.Rows.Count - 2
Dim vals As New List(Of String)
For j As Integer = 0 To columnWriteOrder.Length - 1
Dim val = tbl.Rows(i).Item(columnWriteOrder(j)).ToString()
vals.Add(val)
Next
writer.WriteLine(String.Join(vbTab, vals))
Next
End Using
End Sub
Private Sub PopulateSheetNames()
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
If cboSheet.SelectedIndex >= 0 Then
Dim tableName = cboSheet.SelectedItem.ToString()
Dim dt As DataTable = tables(tableName)
dgProposte.DataSource = dt
End If
End Sub
Private Sub bnLoad_Click(sender As Object, e As EventArgs) Handles bnLoad.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xlsx)|*.xlsx|(*.xls)|*.xls", .InitialDirectory = "C:\temp"}
If ofd.ShowDialog() <> DialogResult.OK Then
Exit Sub
End If
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim edsc = New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}}
Dim result As DataSet = reader.AsDataSet(edsc)
tables = result.Tables
End Using
End Using
PopulateSheetNames()
End Using
End Sub
Private Sub bnSaveAsCsv_Click(sender As Object, e As EventArgs) Handles bnSaveAsCsv.Click
If cboSheet.SelectedIndex < 0 Then
MessageBox.Show("Please select a sheet name.", "No sheet name selected", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
Dim sheetName = cboSheet.SelectedItem.ToString()
If Not String.IsNullOrEmpty(sheetName) Then
WriteToCsv(sheetName, "C:\temp\Prova.csv")
MessageBox.Show("Dati Esportati.", "Dati Esportati", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
End Class
我更改了按钮的名称,因为“Button1”和“Button2”没有描述性。
(我设置了OpenFileDialog的.InitialDirectory是因为方便我。)
我需要了解是否有可能在 VB.NET 内读取 Excel 文件的列并以不同的顺序将它们写入 CSV 文件。
实际中,我们发送的Excel文件有6栏:“金额”、“分公司”、“库存”、“方案”、“数量”、“类型”。公司管理系统接受具有不同顺序列的文本文件:“分支”、“库存”、“金额”、“数量”、“类型”、“建议”。这对我来说是个问题,因为当我去转换它时,我的 ERP无法识别该列位于不同的位置。
我到达了具体问题,我希望有可能阅读这些列并通过脚本使它们能够根据我决定的位置来定位它们。
我尝试使用此代码导入并转换为 txt,但我需要另一个脚本:
Imports System.IO
Imports ExcelDataReader
Imports System.Text
Public Class Form1
Dim tables As DataTableCollection
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xls)|*.xls|(*.xls)|*.xlsx"}
If ofd.ShowDialog() = DialogResult.OK Then
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim result As DataSet = reader.AsDataSet(New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}})
tables = result.Tables
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Using
End Using
End If
End Using
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
Dim dt As DataTable = tables(cboSheet.SelectedItem.ToString())
dgProposte.DataSource = dt
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim writer As TextWriter = New StreamWriter("C:\Users\antonio\Desktop\Prova.txt")
For i As Integer = 0 To dgProposte.Rows.Count - 2 Step +1
For j As Integer = 0 To dgProposte.Columns.Count - 1 Step +1
writer.Write(vbTab & dgProposte.Rows(i).Cells(j).Value.ToString() & vbTab & "")
Next
writer.WriteLine("")
Next
writer.Close()
MessageBox.Show("Dati Esportati")
End Sub
为什么不映射数据的 DTO table?
Public Class MioDto
Property campoUno As String
Property campoDue As String
'...ecc
End Class
然后你可以在一个cicle中填充一个dto...
Dim a As New MioDto() With {.campoUno="...", campoDue="..."}
或者如果您愿意,可以使用
https://github.com/AutoMapper/AutoMapper
填写 Dto class 后,您可以使用它生成包含您或首选订单的 txt。
您通过导入 Excel sheet(s) 得到的表设置了它们的列名,您可以按列名索引该列。
所以,稍微调整一下,找出一些方法:
Imports System.IO
Imports ExcelDataReader
Public Class Form1
Dim tables As DataTableCollection
Private Sub WriteToCsv(tableName As String, filename As String)
Dim columnWriteOrder = {"branch", "stock", "amount", "quantity", "type", "proposal"}
Using writer As TextWriter = New StreamWriter(filename)
Dim tbl = tables(tableName)
For i As Integer = 0 To dgProposte.Rows.Count - 2
Dim vals As New List(Of String)
For j As Integer = 0 To columnWriteOrder.Length - 1
Dim val = tbl.Rows(i).Item(columnWriteOrder(j)).ToString()
vals.Add(val)
Next
writer.WriteLine(String.Join(vbTab, vals))
Next
End Using
End Sub
Private Sub PopulateSheetNames()
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
If cboSheet.SelectedIndex >= 0 Then
Dim tableName = cboSheet.SelectedItem.ToString()
Dim dt As DataTable = tables(tableName)
dgProposte.DataSource = dt
End If
End Sub
Private Sub bnLoad_Click(sender As Object, e As EventArgs) Handles bnLoad.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xlsx)|*.xlsx|(*.xls)|*.xls", .InitialDirectory = "C:\temp"}
If ofd.ShowDialog() <> DialogResult.OK Then
Exit Sub
End If
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim edsc = New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}}
Dim result As DataSet = reader.AsDataSet(edsc)
tables = result.Tables
End Using
End Using
PopulateSheetNames()
End Using
End Sub
Private Sub bnSaveAsCsv_Click(sender As Object, e As EventArgs) Handles bnSaveAsCsv.Click
If cboSheet.SelectedIndex < 0 Then
MessageBox.Show("Please select a sheet name.", "No sheet name selected", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
Dim sheetName = cboSheet.SelectedItem.ToString()
If Not String.IsNullOrEmpty(sheetName) Then
WriteToCsv(sheetName, "C:\temp\Prova.csv")
MessageBox.Show("Dati Esportati.", "Dati Esportati", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
End Class
我更改了按钮的名称,因为“Button1”和“Button2”没有描述性。
(我设置了OpenFileDialog的.InitialDirectory是因为方便我。)