VB.NET OpenXML to Read Excel File - vb.net

I have been searching for a way to effectively read an Excel file and have found the following code for parsing and reading a large spreadsheet:
Public Sub ExcelProcessing()
Dim strDoc As String = "C:\Documents and Settings\Practice.xlsx"
Dim txt As String
Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Open(strDoc, False)
Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart
Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.First()
Dim reader As OpenXmlReader = OpenXmlReader.Create(worksheetPart)
Dim text As String
While reader.Read()
If reader.ElementType = GetType(CellValue) Then
text = reader.GetText()
MessageBox.Show(text)
End If
End While
The issue is where I assign reader.GetText() to my string. The value passed is a small integer while the actual cell value is a string. The messagebox fires once for each populated cell, so this tells me the code is finding cells that contain values; however, I can not extract the actual "inner text" of the cell.
Thoughts? Suggestions?

I found my answer; I need to reference the sharedstringtable and pull out the inner text from there:
Dim strDoc As String = "C:\Documents and Settings\Practice.xlsx"
Dim txt As String
Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Open(strDoc, False)
Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart
Dim shareStringPart As SharedStringTablePart = workbookPart.SharedStringTablePart
For Each Item As SharedStringItem In shareStringPart.SharedStringTable.Elements(Of SharedStringItem)()
MessageBox.Show(Item.InnerText)
Next

Related

How insert password when i try to read my Excel? vb.net

I try to read a Excel, but have password (i know password) how insert password to read excel. My Code is like that:
Dim FileName As String = Path.GetFileName(FileUpload1.PostedFile.FileName)
Dim Extension As String = Path.GetExtension(FileUpload1.PostedFile.FileName)
'Dim FolderPath As String = ConfigurationManager.AppSettings("Upload")
Dim FilePath As String = Server.MapPath("~") & "\Upload\" & FileName
FileUpload1.SaveAs(FilePath)
Dim existingFile = New FileInfo(FilePath)
Dim pack As ExcelPackage = New ExcelPackage(existingFile)
Dim workBook As ExcelWorkbook = pack.Workbook
If workBook.Worksheets.Count > 0 Then ...
Error display on row:
Dim pack As ExcelPackage = New ExcelPackage(existingFile)
Error:
Can not open the package. Package is an OLE compound document. If this
is an encrypted package, please supply the password

VB - Had a function working, doesn't anymore

EDIT: Ok, it's because I'm using 2.0 Framework. Any ideas how I can modify that area or alternatives? I have to, unfortunately, stick with 2.0
Dim dir2 As New DirectoryInfo("d:\input")
Dim sw2 As New StreamWriter("d:\input\reportCond.txt")
For Each fi2 As FileInfo In dir2.GetFiles("report.txt")
Dim sr2 As New StreamReader(fi2.FullName)
While Not sr2.EndOfStream
Dim sLine As String = sr2.ReadLine
Dim myPath As String = sLine
Dim fileName As String =System.IO.Path.GetFileNameWithoutExtension(myPath)
Dim letters As String = fileName.Where(Function(c) Char.IsLetter(c)).ToArray
Dim comp As String = sLine.Substring(28)
sw2.WriteLine(letters)
End While
Next
The Code above was working fine yesterday, today it doesn't and I can't figure out why. The only difference was yesterday I ran it on VS2013, today it doesn't work on VS2010.
I get an error on Function saying "expression expected"
And another one on sw2.WriteLine(letters) saying "Name 'letters' is not declared.
Here is how the linq Where part can be replaced to get the letters variable - which contains characters from the file name.
dim c as char
Dim letters As String
for each c in s
if char.IsLetter(c)
letters += c
end if
next
I would use the StringBuilder class to build the string:
Dim dir2 As New DirectoryInfo("d:\input")
Dim sw2 As New StreamWriter("d:\input\reportCond.txt")
For Each fi2 As FileInfo In dir2.GetFiles("report.txt")
Dim sr2 As New StreamReader(fi2.FullName)
While Not sr2.EndOfStream
Dim sLine As String = sr2.ReadLine
Dim myPath As String = sLine
Dim fileName As String =System.IO.Path.GetFileNameWithoutExtension(myPath)
' Build string
Dim sb As New System.Text.StringBuilder()
For Each c As Char In fileName
If Char.IsLetter(c) Then
sb.Append(c)
End If
Next
Dim comp As String = sLine.Substring(28)
' Here's the string you built
Dim letters As String = sb.ToString()
sw2.WriteLine(letters)
End While
Next
A .Net 2.0 framework alternative to the Where extension method could be:
Dim letters As String = Array.FindAll(fileName.ToCharArray(), AddressOf Char.IsLetter)
This will create a new array of chars whose elementes will be all chars of fileName.ToCharArray for wich Char.IsLetter is True

Create a search bar for hex values

My current code requires me to edit the search value while the project is still in VB. I have not been able to figure out how to code the input value to use a textbox for search. I would really like to be able to build this project and use it without having VB open. Below is my code:
Dim filePath As String = Me.TextBox1.Text 'The path for the file you want to search
Dim fInfo As New FileInfo("C:\MyFile.File")
Dim numBytes As Long = fInfo.Length
Dim fStream As New FileStream("C:\MyFile.File", FileMode.Open, FileAccess.Read)
Dim br As New BinaryReader(fStream)
Dim data As Byte() = br.ReadBytes(CInt(numBytes))
Dim pos As Integer = -1
Dim searchItem As String = "b6" 'The hex values of what you want to search
Dim searchItemAsInteger As Integer
Dim locationsFound As New List(Of Integer)
MessageBox.Show("Wait while I Scan?")
br.Close()
fStream.Close()
Integer.TryParse(searchItem, Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, searchItemAsInteger)
For Each byteItem As Byte In data
pos += 1
If CInt(byteItem) = searchItemAsInteger Then
locationsFound.Add(pos)
Me.ListBox1.Items.Add(Hex(pos))
End If
Next
For i As Integer = 0 To Me.ListBox1.Items.Count - 1
Me.ListBox1.SetSelected(i, True)
Next
End Sub
Place a textbox named "txtHexValueToSearch" inside Form1. And then replaces the code that is commented:
' Dim searchItem As String = "b6" 'The hex values of what you want to search
Dim searchItem As String = Me.txtHexValueToSearch.Text 'The hex values of what you want to search

How to add a string to multiple string for printing external

This is going to be a long one, but easy fix.
So i've manage to convert a pdf to string, then able to print an external pdf simply by putting the name of the file in a textbox.
I've also figured how to extract certain text from the pdf string, now the certain text are also files located in an external location (I use c:\temp\ for testing).
Which leaves me with one problem, the text I extract, I use shellexecute to print, works fine if its one string. however, If the file name I extract is more than one it will count it as a single string, thus adding the location and .pdf to that one string. instead of the two or more strings. which will do something like this:
As you can see, it will send that to the printer. I want to send one at a time to the printer. like this:
I've tried using an Arraylist and various methods. but my own lack of knowledge, I cannot figure it out.
I'm thinking a "for loop" will help me out. any ideas?
Below is my code.
Dim pdffilename As String = Nothing
pdffilename = RawTextbox.Text
Dim filepath = "c:\temp\" & RawTextbox.Text & ".pdf"
Dim thetext As String
thetext = GetTextFromPDF(filepath) ' converts pdf to text from a function I didnt show.
Dim re As New Regex("[\t ](?<w>((asm)|(asy)|(717)|(ssm)|(715)|(818))[a-z0-9]*)[\t ]", RegexOptions.ExplicitCapture Or RegexOptions.IgnoreCase Or RegexOptions.Compiled) ' This filters out and extract certain keywords from the PDF
Dim Lines() As String = {thetext}
Dim words As New List(Of String)
For Each s As String In Lines
Dim mc As MatchCollection = re.Matches(s)
For Each m As Match In mc
words.Add(m.Groups("w").Value)
Next
RawRich4.Text = String.Join(Environment.NewLine, words.ToArray)
Next
'This is where I need help with the code. how to have "words" putout "c:\temp\" & RawRich4.Text & ".pdf" with each keyword name
Dim rawtoprint As String = String.Join(Environment.NewLine, words.ToArray)
Dim defname As String = Nothing
defname = RawRich4.Text
rawtoprint = "c:\temp\" & RawRich4.Text & ".pdf"
Dim psi As New System.Diagnostics.ProcessStartInfo()
psi.UseShellExecute = True
psi.Verb = "print"
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
psi.FileName = (rawtoprint) ' this is where the error occurs it doesn't send both files separately to the printer, it tries to send it as one name
MessageBox.Show(rawtoprint) ' This is just to test the output, this will be removed.
'Process.Start(psi)
End Sub
Updated.
Imports System.Text.RegularExpressions
Module Program
Sub Main()
Dim pdffilename As String = RawTextbox.Text
Dim filepath = "c:\temp\" & RawTextbox.Text & ".pdf"
Dim thetext As String
thetext = GetTextFromPDF(filepath) ' converts pdf to text from a function I didnt show.
'thetext = "Random text here and everywhere ASM00200207 1 1 same here bah boom 12303 doh hel232 ASM00200208 1 2 "
Dim pattern As String = "(?i)[\t ](?<w>((asm)|(asy)|(717)|(ssm)|(715)|(818))[a-z0-9]*)[\t ]"
For Each m As Match In rgx.Matches(thetext, pattern)
'Console.WriteLine("C:\temp\" & Trim(m.ToString) & ".pdf")
RawPrintFunction("C:\temp\" & Trim(m.ToString) & ".pdf")
Next
End Sub
Function RawPrintFunction(ByVal rawtoprint As String) As Integer
Dim psi As New System.Diagnostics.ProcessStartInfo()
psi.UseShellExecute = True
psi.Verb = "print"
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
MessageBox.Show(rawtoprint) This will be removed, this is just for testing to see what files will be printed
'Process.Start(psi) This will be uncomment.
return 0
End Function
End Module
If I don't misunderstand the code -since I can't test and run it here- you can iterate through file names stored in words variable and send it to printer. Following is an example on how to do that :
....
....
Dim Lines() As String = {thetext}
Dim words As New List(Of String)
For Each s As String In Lines
Dim mc As MatchCollection = re.Matches(s)
For Each m As Match In mc
words.Add(m.Groups("w").Value)
Next
RawRich4.Text = String.Join(Environment.NewLine, words.ToArray)
Next
For Each fileName As String In words
Dim rawtoprint As String
rawtoprint = "c:\temp\" & fileName & ".pdf"
Dim psi As New System.Diagnostics.ProcessStartInfo()
psi.UseShellExecute = True
psi.Verb = "print"
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
psi.FileName = (rawtoprint) ' this is where the error occurs it doesn't send both files separately to the printer, it tries to send it as one name
MessageBox.Show(rawtoprint) ' This is just to test the output, this will be removed.
'Process.Start(psi)
Next

streamwriter in windows store app - write text to file in VB

Does anybody have VB code to emulate Streamwriter for Windows Store?
I know it's been replaced by StorageFolder class but there is no VB sample in MSDN and I can't seem to translate properly from c# examples. Any help would be appreciated. I am just trying to write text (CSV) to a file and save it to the documents folder. In the code below windows store want a stream instead of strPath when I try dim-ing a streamwriter. (been playing with pickerdialog too, but that might be the next hurdle).
Dim strpath As String = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary & "\" & strFileName
'Build String for file*******************
Dim swExport As StreamWriter = New StreamWriter(strpath)
swExport.Flush()
For x = 0 To intCount - 1
strLine = "WriteSomeText"
swExport.WriteLine(strLine)
Next x
Possibly the simplest approach would be to use a MemoryStream if you like StreamWriter, so something like:
Dim sessionData As New MemoryStream()
' TODO: stage data in sessionData
Dim swExport As StreamWriter = New StreamWriter(sessionData)
swExport.Flush()
For x = 0 To intCount - 1
strLine = "WriteSomeText"
swExport.WriteLine(strLine)
Next x
Dim file As StorageFile = await ApplicationData.Current.RoamingFolder.CreateFileAsync("towns.json", CreationCollisionOption.ReplaceExisting)
Using (fileStream As Stream = await file.OpenStreamForWriteAsync())
sessionData.Seek(0, SeekOrigin.Begin)
await sessionData.CopyToAsync(fileStream)
await fileStream.FlushAsync()
End Using
I was making it too difficult. To write to a file I just needed to use storagefolder and storagefile. I have also included the FileSavePicker in the code (note that filetypechoices is mandatory)
Private Async Function btnExport_Click(sender As Object, e As RoutedEventArgs) As Task
'Calls Filepicker to determine location
'Calls Sqlite to select ALL
'Creates CSV file to be saved at location chosen
'save to file
Dim intCount As Integer = "5"
Dim x As Integer
Dim strLine As String 'hold each line for export file
'Create FileName based on date
Dim strDate As String = Date.Today.ToString("MMddyyyy")
Dim strFileName As String = "Export" & strDate & ".csv"
' Configure save file dialog box
Dim dlgPicker As New Windows.Storage.Pickers.FileSavePicker
'add types for picker (manditory field)
Dim types = New List(Of String)
types.Add(".csv")
types.Add(".txt")
'set picker parameters
dlgPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Downloads
dlgPicker.SuggestedFileName = strFileName '"Document" '
dlgPicker.FileTypeChoices.Add("CSV/TXT", types) 'manditory
dlgPicker.DefaultFileExtension = ".csv" 'Filter files by extension
dlgPicker.CommitButtonText = "Save"
' Show save file dialog box
Dim SaveCSV = Await dlgPicker.PickSaveFileAsync()
'************************get data************
Dim sbExport As Text.StringBuilder = New Text.StringBuilder
sbExport.AppendLine(strHeader)
For x = 0 To intCount - 1
strLine = "Get the text you want to write here"
sbExport.AppendLine(strLine)
Next x
'************************************
'write data to file
Await FileIO.WriteTextAsync(SaveCSV, sbExport.ToString)
Dim mb As MessageDialog = New MessageDialog("Done")
Await mb.ShowAsync()
End Function