.NET 3.x Нужны компоненты для конвертации .xls в .xml и обратно - Visual Basic .NET
Формулировка задачи:
Доброго! не могу найти компоненты для конвертации .xls в .xml и обратно. смотрел NPOI(так и не нашел решения) , GemBox.Spreadsheet (бесплатная версия не поддерживает формат xml)
.xml - удобный формат для редактирования без установленного excel.
нашел это -https://code.msdn.microsoft.com/offi...-file-7a9bb404
ошибка - для 2007 и 2003 - файл поврежден
нет не каких идей ? как конвертировать автоматически без установленного excel ?
Решение задачи: «.NET 3.x Нужны компоненты для конвертации .xls в .xml и обратно»
textual
Листинг программы
Imports System.Xml
Imports System.IO
Imports System.Text
Imports System.IO.Compression
Imports Shell32
Public Class Form1
Dim fold As String = My.Computer.FileSystem.SpecialDirectories.Temp & "\tmp_excel"
Dim filexcel As String = "C:\test\Книга22.xlsx"
Dim tmp_filexcel As String = Path.ChangeExtension(Me.filexcel, ".zip")
Dim xr As XmlReader
Dim xrw As XmlTextReader
Dim ch_n(,) As String ' (имя,тип,позиция)
Dim ch_v() 'значения ячеек в случае s
Dim i As Integer
Dim numcv, numcn As Integer ' позиции значений
Dim shObj As New Shell32.Shell()
'кнопка распокавать
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Directory.Exists(fold) Then
Directory.Delete(fold, True)
End If
Directory.CreateDirectory(fold)
If File.Exists(Me.filexcel) Then
IO.File.Move(filexcel, tmp_filexcel)
End If
Dim output As Shell32.Folder = shObj.NameSpace(fold)
Dim input As Shell32.Folder = shObj.NameSpace(tmp_filexcel)
If File.Exists(tmp_filexcel) Then
output.CopyHere((input.Items), 16)
MsgBox("done")
Else
MsgBox("файл не найден")
End If
End Sub
''кнопка упаковать
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If File.Exists(tmp_filexcel) Then
File.Delete(tmp_filexcel)
End If
Dim ZipHeader As Byte() = New Byte() {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim fs As FileStream = File.Create(tmp_filexcel)
fs.Write(ZipHeader, 0, ZipHeader.Length)
fs.Flush()
fs.Close()
fs = Nothing
Dim sh As New Shell32.Shell()
Dim input As Shell32.Folder = sh.NameSpace(fold)
Dim output As Shell32.Folder = sh.NameSpace(tmp_filexcel)
output.CopyHere(input.Items, 16)
File.Move(tmp_filexcel, filexcel)
End Sub
'кнопка значение ячейки
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
xr = XmlReader.Create(fold & "\xl\worksheets\sheet1.xml")
i = 0
Dim tmp_n() As String
Do While xr.Read()
ReDim Preserve tmp_n(i)
ReDim Preserve ch_n(2, i)
If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "c" Then
ch_n(0, i) = xr.GetAttribute("r") 'имена
'xr.GetAttribute(0).ToString
tmp_n(i) = ch_n(0, i)
Try
ch_n(1, i) = xr.GetAttribute("t") 'типы значений
Catch ex As Exception
ch_n(1, i) = "i"
End Try
ch_n(2, i) = xr.ReadElementString ' расположение в случае "s"
i += 1
End If
Loop
numcn = Array.IndexOf(tmp_n, TextBox2.Text)
xr.Close()
Erase tmp_n
If numcn <> -1 Then
xr = XmlReader.Create(fold & "\xl\sharedStrings.xml")
i = 0
Do While xr.Read()
If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "t" Then
ReDim Preserve ch_v(i)
ch_v(i) = xr.ReadElementString
i += 1
End If
Loop
If ch_n(1, numcn) = "s" Then
TextBox1.Text = ch_v(Convert.ToInt32(ch_n(2, numcn)))
Else
TextBox1.Text = ch_n(2, numcn)
End If
xr.Close()
Else
TextBox1.Text = "не найдено"
End If
''Erase ch_n
End Sub
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
End Sub
'кнопка заменить значение
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
If CheckBox1.Checked = True Then
writeh(TextBox4.Text, "integer")
Else
writeh(TextBox4.Text, "string")
End If
End Sub
Private Function writeh(strock As String, t As String) As String
xrw = New XmlTextReader(fold & "\xl\sharedStrings.xml")
Dim doc As New XmlDocument()
doc.Load(xrw)
xrw.Close()
xrw = New XmlTextReader(fold & "\xl\worksheets\sheet1.xml")
Dim doc1 As New XmlDocument()
doc1.Load(xrw)
xrw.Close()
Dim oldCd As XmlNode
Dim root As XmlElement
Dim nsmgr As XmlNamespaceManager
Dim elemList As XmlNodeList
If ch_n(1, numcn) = "s" Then
If t = "string" Then
root = doc.DocumentElement
nsmgr = New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ss", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
oldCd = root.SelectSingleNode("/ss:sst/ss:si[" & (Convert.ToInt32(ch_n(2, numcn)) + 1).ToString & "]", nsmgr) '/ss:sst/
Dim newCd As XmlElement = doc.CreateElement("si", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
Dim value = newCd.AppendChild(doc.CreateElement("t", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
value.AppendChild(doc.CreateTextNode(strock))
'root.InsertAfter(newCd, newCd) TextBox4
root.ReplaceChild(newCd, oldCd)
doc.Save(fold & "\xl\sharedStrings.xml")
writeh = "done"
MsgBox(writeh)
Else
'удалить узел в sharedStrings.xml
root = doc.DocumentElement
nsmgr = New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ss", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
oldCd = root.SelectSingleNode("/ss:sst/ss:si[" & (Convert.ToInt32(ch_n(2, numcn)) + 1).ToString & "]", nsmgr)
root.RemoveChild(oldCd)
doc.Save(fold & "\xl\sharedStrings.xml")
'заменить значение в sheet1.xml
root = doc1.DocumentElement
nsmgr = New XmlNamespaceManager(doc1.NameTable)
nsmgr.AddNamespace("s1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")
nsmgr.AddNamespace("s2", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
'numcn
oldCd = root.SelectSingleNode("//s2:c[" & (numcn + 1).ToString & "]", nsmgr)
Dim newCd As XmlElement = doc1.CreateElement("c", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
newCd.SetAttribute("r", ch_n(0, numcn))
'newCd.SetAttribute("t", "s")
Dim value = newCd.AppendChild(doc1.CreateElement("v", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
value.AppendChild(doc1.CreateTextNode(TextBox4.Text))
oldCd.ParentNode.ReplaceChild(newCd, oldCd)
doc1.Save(fold & "\xl\worksheets\sheet1.xml")
writeh = "done"
MsgBox(writeh)
End If
Else
If t = "string" Then
' добавить узел с значением в sharedStrings.xml
root = doc.DocumentElement
elemList = root.GetElementsByTagName("c")
Dim numstr As Integer = elemList.Count + 1
nsmgr = New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ss", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
Dim newCd As XmlElement = doc.CreateElement("si", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
Dim value = newCd.AppendChild(doc.CreateElement("t", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
value.AppendChild(doc.CreateTextNode(TextBox4.Text))
root.AppendChild(newCd)
doc.Save(fold & "\xl\sharedStrings.xml")
' заменить значение на порядковый номер
root = doc1.DocumentElement
nsmgr = New XmlNamespaceManager(doc1.NameTable)
nsmgr.AddNamespace("s1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")
nsmgr.AddNamespace("s2", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
oldCd = root.SelectSingleNode("//s2:c[" & (numcn + 1).ToString & "]", nsmgr)
Dim newCd2 As XmlElement = doc1.CreateElement("c", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
newCd2.SetAttribute("r", ch_n(0, numcn))
newCd2.SetAttribute("t", "s")
Dim value2 = newCd2.AppendChild(doc1.CreateElement("v", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
value2.AppendChild(doc1.CreateTextNode(numstr.ToString))
oldCd.ParentNode.ReplaceChild(newCd2, oldCd)
doc1.Save(fold & "\xl\worksheets\sheet1.xml")
writeh = "done"
MsgBox(writeh)
Else
root = doc1.DocumentElement
nsmgr = New XmlNamespaceManager(doc1.NameTable)
nsmgr.AddNamespace("s1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")
nsmgr.AddNamespace("s2", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
'numcn
oldCd = root.SelectSingleNode("//s2:c[" & (numcn + 1).ToString & "]", nsmgr)
Dim newCd As XmlElement = doc1.CreateElement("c", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
newCd.SetAttribute("r", ch_n(0, numcn))
'newCd.SetAttribute("t", "s")
Dim value = newCd.AppendChild(doc1.CreateElement("v", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
value.AppendChild(doc1.CreateTextNode(TextBox4.Text))
oldCd.ParentNode.ReplaceChild(newCd, oldCd)
doc1.Save(fold & "\xl\worksheets\sheet1.xml")
writeh = "done"
MsgBox(writeh)
End If
End If
End Function
'кнопка объеденена
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim tmp_ch_sn() As String
Dim tmp_ch_vn() As String
Dim info As String = "не найдено"
i = 0
xr = XmlReader.Create(fold & "\xl\worksheets\sheet1.xml")
Do While xr.Read()
ReDim Preserve tmp_ch_sn(i)
ReDim Preserve tmp_ch_vn(i)
Try
If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "mergeCell" Then
tmp_ch_sn(i) = xr.GetAttribute("ref")
tmp_ch_vn(i) = xr.GetAttribute("ref").Split(":")(0)
i += 1
numcv = Array.IndexOf(tmp_ch_vn, TextBox2.Text)
If numcv <> -1 Then
info = tmp_ch_sn(numcn)
End If
End If
Catch ex As Exception
End Try
TextBox3.Text = info
Loop
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
End Sub
End Class