Article 1: Generic Excel Importer Class for your ABMUpload component
For my ABMaterial App, I needed a Ms Excel worksheet importer, so I decided to build one.
For this, you will need the Poi libraries, available here..
I have an ABMUpload component in my page, and a combobox to select my template, so when I drop a file there, it gets uploaded to the server and the excel importer code is fired. The ABMCombo is loaded up with the 'Description' column and the 'id' column of my templates table.
My Page_FileUploaded method...
This class assumes that you have a table that stores your template data, i.e. a structure or definition of the stuff you want to import, see figure 1 below:
Figure 1
Usage: Here I want to import Resources to the resources table, from the WB1, starting at row 1 and ending at row 10 of the worksheet. The data should be writtem to the firstname, lastname, dob and jobtitle fields in the table, from column A, B, E and F respectively, but read the column names should they change from the resourcename, surname, dateofbirth, job columns in the templates table.
The output to copy and paste your ABMaterial project will be..
The additional methods on my ABMShared...
Ta: Enjoy...
For my ABMaterial App, I needed a Ms Excel worksheet importer, so I decided to build one.
For this, you will need the Poi libraries, available here..
I have an ABMUpload component in my page, and a combobox to select my template, so when I drop a file there, it gets uploaded to the server and the excel importer code is fired. The ABMCombo is loaded up with the 'Description' column and the 'id' column of my templates table.
My Page_FileUploaded method...
B4X:
Sub Page_FileUploaded(FileName As String, success As Boolean)
myToastId = myToastId + 1
If success Then
page.ShowToast("toast" & myToastId, "toastgreen", "File " & FileName & " uploaded!", 3000)
Else
page.ShowToast("toast" & myToastId, "toastred", "File " & FileName & " not uploaded!", 3000)
End If
Dim actualFile As String = File.combine(File.DirApp, DownloadFolder & FileName)
ExcelImportresources(actualFile)
page.ws.Flush ' IMPORTANT
End Sub
This class assumes that you have a table that stores your template data, i.e. a structure or definition of the stuff you want to import, see figure 1 below:
Figure 1
Usage: Here I want to import Resources to the resources table, from the WB1, starting at row 1 and ending at row 10 of the worksheet. The data should be writtem to the firstname, lastname, dob and jobtitle fields in the table, from column A, B, E and F respectively, but read the column names should they change from the resourcename, surname, dateofbirth, job columns in the templates table.
B4X:
Dim xls As clsExcelmporter
xls.Initialize("Resources Template","resources","WB1",1,10,True,True)
xls.SetTemplate("resourcestemplate","wsname","startrow","endrow")
xls.AddColumn("firstname","resourcename","","A")
xls.addcolumn("lastname","surname","","B")
xls.addcolumn("dob","dateofbirth","","E")
xls.addcolumn("jobtitle","job","","F")
xls.Build(File.DirApp,"resources.txt")
The output to copy and paste your ABMaterial project will be..
B4X:
Sub ExcelImportresources(xlsFileName As String)
'get the iym template to use
Dim cboTemplate As ABMCombo = page.Component("cboTemplate")
Dim tempID As Int = cboTemplate.GetActiveItemId
If tempID <= 0 Then
myToastId = myToastId + 1
page.ShowToast("toast" & myToastId, "toastred", "The Resources Template should be selected first!", 3000)
Return
End If
If File.Exists("",xlsFileName) = False Then Return
Dim jsql As SQL = ABMShared.sqlget
'read the template from file and set the needed properties
Dim temp As Map = ABMShared.SQLRecordRead(jsql,"resourcestemplate","id",tempID)
If temp.IsInitialized = False Then
myToastId = myToastId + 1
page.ShowToast("toast" & myToastId, "toastred", "The Resources Template could not be read, please correct this!", 3000)
Return
End If
Dim worksheetname As String = temp.GetDefault("wsname","WB1")
Dim startrow As Long = temp.GetDefault("startrow",1)
startrow = startrow - 1
Dim endrow As Long = temp.GetDefault("endrow",10)
'start processing the workbook
Dim wb As PoiWorkbook
'initialize an existing workbook
wb.InitializeExisting("",xlsFileName,"")
'get the worksheet names
Dim wsl As List = wb.GetSheetNames
'find the summary work sheet position
Dim summaryPos As Int = wsl.IndexOf(worksheetname)
If summaryPos = -1 Then Return
'get the workbook
Dim wSheet As PoiSheet = wb.GetSheet(summaryPos)
Dim rCnt As Long
Dim Records as List
Records.initialize
'Get the row positions for the fields
'Get the column names (A-Z) for the fields
Dim resourcenameCol As String = temp.GetDefault("resourcename","A")
Dim surnameCol As String = temp.GetDefault("surname","B")
Dim dateofbirthCol As String = temp.GetDefault("dateofbirth","E")
Dim jobCol As String = temp.GetDefault("job","F")
'Get the column positions (1..n) for the fields
Dim resourcenameColPos As Int = ABMShared.GetColumnPos(resourcenameCol)
Dim surnameColPos As Int = ABMShared.GetColumnPos(surnameCol)
Dim dateofbirthColPos As Int = ABMShared.GetColumnPos(dateofbirthCol)
Dim jobColPos As Int = ABMShared.GetColumnPos(jobCol)
For rowCnt = startrow To endrow
Dim resourcename As String = ABMShared.GetRowCellValue(wSheet,rowCnt, resourcenameCol)
Dim surname As String = ABMShared.GetRowCellValue(wSheet,rowCnt, surnameCol)
Dim dateofbirth As String = ABMShared.GetRowCellValue(wSheet,rowCnt, dateofbirthCol)
Dim job As String = ABMShared.GetRowCellValue(wSheet,rowCnt, jobCol)
'Create map To hold the record To add
Dim record As Map
record.initialize
record.put("firstname",resourcename)
record.put("lastname",surname)
record.put("dob",dateofbirth)
record.put("jobtitle",job)
Records.Add(record)
Next
'Add all records to the table
ABMShared.SQLRecordInsertMaps(jSQL,"resources",Records)
ABMShared.SQLClose(jsql)
myToastId = myToastId + 1
page.ShowToast("toast" & myToastId, "toastgreen", "Resources Template data imported successfully!", 3000)
End Sub
The additional methods on my ABMShared...
B4X:
Sub PoiCellReturn(cell As PoiCell) As String
If cell.IsInitialized = True Then
Select Case cell.CellType
Case cell.TYPE_NUMERIC
Return cell.ValueNumeric
Case cell.TYPE_STRING
Return cell.ValueString
Case cell.TYPE_FORMULA
Return cell.ValueFormula
Case cell.TYPE_BLANK
Return ""
Case cell.TYPE_BOOLEAN
Return cell.ValueBoolean
Case cell.TYPE_ERROR
Return ""
Case Else
Return cell.Value
End Select
Else
Return ""
End If
End Sub
'return the column position
Sub GetColumnPos(colAlpha As String) As Int
Select Case colAlpha.tolowercase
Case "a"
Return 1
Case "b"
Return 2
Case "c"
Return 3
Case "d"
Return 4
Case "e"
Return 5
Case "f"
Return 6
Case "g"
Return 7
Case "h"
Return 8
Case "i"
Return 9
Case "j"
Return 10
Case "k"
Return 11
Case "l"
Return 12
Case "m"
Return 13
Case "n"
Return 14
Case "o"
Return 15
Case "p"
Return 16
Case "q"
Return 17
Case "r"
Return 18
Case "s"
Return 19
Case "t"
Return 20
Case "u"
Return 21
Case "v"
Return 22
Case "w"
Return 23
Case "x"
Return 24
Case "y"
Return 25
Case "z"
Return 26
Case "aa"
Return 27
Case "ab"
Return 28
Case "ac"
Return 29
Case "ad"
Return 30
Case "ae"
Return 31
Case "af"
Return 32
Case "ag"
Return 33
Case "ah"
Return 34
Case "ai"
Return 35
Case "aj"
Return 36
Case "ak"
Return 37
Case "al"
Return 38
Case "am"
Return 39
Case "an"
Return 40
Case "ao"
Return 41
Case "ap"
Return 42
Case "aq"
Return 43
Case "ar"
Return 44
Case "as"
Return 45
Case "at"
Return 46
Case "au"
Return 47
Case "av"
Return 48
Case "aw"
Return 49
Case "ax"
Return 50
Case "ay"
Return 51
Case "az"
Return 52
End Select
End Sub
Sub GetRowCellValue(ws As PoiSheet, rowpos As Int, colAlpha As String) As String
Dim cell As PoiCell = GetPoiCell(ws,rowpos,colAlpha)
Return PoiCellReturn(cell)
End Sub
Sub GetPoiCell(ws As PoiSheet, rowPos As Int, colAlpha As String) As PoiCell
Try
Dim rowP As Int = rowPos - 1
Dim colP As Int = 0
If IsNumber(colAlpha) = False Then
colP = GetColumnPos(colAlpha) - 1
Else
colP = colAlpha -1
End If
Dim row As PoiRow = ws.GetRow(rowP)
row.IsInitialized
Dim cell As PoiCell = row.GetCell(colP)
cell.IsInitialized
Return cell
Catch
Return Null
End Try
End Sub
B4X:
Sub GetPoiCellValue(row As PoiRow, colAlpha As String) As String
Dim cell As PoiCell = GetPoiRowPoiCell(row,colAlpha)
Return PoiCellReturn(cell)
End Sub
Sub GetPoiRow(ws As PoiSheet, rowPos As Int) As PoiRow
Try
Dim rowP As Int = rowPos - 1
Dim row As PoiRow = ws.GetRow(rowP)
row.IsInitialized
Return row
Catch
Return Null
End Try
End Sub
Sub GetPoiRowPoiCell(row As PoiRow, colAlpha As String) As PoiCell
Try
Dim colP As Int = 0
If IsNumber(colAlpha) = False Then
colP = GetColumnPos(colAlpha) - 1
Else
colP = colAlpha -1
End If
Dim cell As PoiCell = row.GetCell(colP)
cell.IsInitialized
Return cell
Catch
Return Null
End Try
End Sub
Ta: Enjoy...