Adding a second sheet & saving it doesn't show in Excel - c#-4.0

I have 2 datable and I added for loop to create the sheet and save it, but when I open excel file I can see only one(1st) sheet.
Please check why 2nd is not added in excel.
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbook wb = xlApp.Worksheets.Add();
Excel.Worksheet ws = null;
Excel.Range chartRange =null;
for(int i=0; i<dataset.Tables.Count; i++)
{
// here I am creating new sheet for each datatable but only 1st datatable value I can see in
XL, 2nd sheet is not created
ws = (Excel.Worksheet)worksheets.Add();
ws.Name = dataset.Table[i].TableName;
//business logic here to assign data
var dgarray = new object[rows.count, columns.count];
//for loop to assign column name
dgarray[0,c] = column name;
//for loop to assign row value
dgarray[rowindex, colindex] = row value;
int rowcount = dgarray.getlength(0);
int columscount = dgarray.getlength(1);
chartRange = (Excel.Range)ws.cells[1,1];
chartRange = chartRange.get_Resize(rowcount,colcount);
chartRange.set_Value(Excel.XlRangeValueDatatype.XlRangeValueDefault,dgarray);
}
((Excel.Worksheet).ws).SaveAs(filename);

Related

VB.NET use Microsoft OpenXML to save excel file

it's my first approach to openxml and I can't get it to work.
Hi want to create an xls file, write a value to specific cells and save it. This is the code I wrote for now, it creates the file but doesn't write any value at all. What I'm missing? Thanks
EDIT: as asked I addedd InsertCellInWorksheet function
Sub Main()
CreateSpreadsheetWorkbook("IMPOVO.XLS")
Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open("IMPOVO.XLS", True)
Using (spreadSheet)
Dim worksheetPart As WorksheetPart = spreadSheet.WorkbookPart.WorksheetParts.First
Dim cell As Cell = InsertCellInWorksheet("A", 1, worksheetPart)
' Set the value of cell A1.
cell.CellValue = New CellValue("Hi World")
cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString)
' Save the new worksheet.
worksheetPart.Worksheet.Save()
End Using
End Sub
Public Sub CreateSpreadsheetWorkbook(ByVal filepath As String)
'Create a spreadsheet document by supplying the filepath.
'By default, AutoSave = true, Editable = true, and Type = xlsx.
Dim spreadsheetDocument As SpreadsheetDocument =
SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook)
'Add a WorkbookPart to the document.
Dim workbookpart As WorkbookPart = spreadsheetDocument.AddWorkbookPart
workbookpart.Workbook = New Workbook
'Add a WorksheetPart to the WorkbookPart.
Dim worksheetPart As WorksheetPart = workbookpart.AddNewPart(Of WorksheetPart)()
worksheetPart.Worksheet = New Worksheet(New SheetData())
'Add Sheets to the Workbook.
Dim sheets As Sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())
'Append a new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet
sheet.Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart)
sheet.SheetId = 1
sheets.Append(sheet)
workbookpart.Workbook.Save()
'Close the document.
spreadsheetDocument.Close()
End Sub
Private Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal worksheetPart As WorksheetPart) As Cell
Dim worksheet As Worksheet = worksheetPart.Worksheet
Dim sheetData As SheetData = worksheet.GetFirstChild(Of SheetData)()
Dim cellReference As String = (columnName + rowIndex.ToString())
' If the worksheet does not contain a row with the specified row index, insert one.
Dim row As Row
If (sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).Count() <> 0) Then
row = sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).First()
Else
row = New Row()
row.RowIndex = rowIndex
sheetData.Append(row)
End If
' If there is not a cell with the specified column name, insert one.
If (row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = columnName + rowIndex.ToString()).Count() > 0) Then
Return row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = cellReference).First()
Else
' Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Dim refCell As Cell = Nothing
For Each cell As Cell In row.Elements(Of Cell)()
If (String.Compare(cell.CellReference.Value, cellReference, True) > 0) Then
refCell = cell
Exit For
End If
Next
Dim newCell As Cell = New Cell
newCell.CellReference = cellReference
row.InsertBefore(newCell, refCell)
worksheet.Save()
Return newCell
End If
End Function
This is just a suggestion, but try explicitly closing the document at the end of the Using block like your code does in the last instruction in the CreateSpreadsheetWorkbook() method to see if that resolved the issue. You may also need to explicitly save the spreadsheet object at the end of the Using block.

Add an Excel Form Control to a file in vb.net

I've got an application written that does a pretty standard dump of a datagridview into an Excel file. The application loops through 12 items and creates a separate sheet in the workbook, then filling in the table using the datagridview.
The export is all good, but what I want to do now is add to every every sheet an additional column that contains a check box on every row in that sheet. It seems the better way to do that is add the form control before the Excel file is saved in the code, but I can't work out if that is possible - Adding a checkbox column to the datagridview doesn't seem to be a viable option.
Code - the dtResults is a datatable filled by a Microsoft SQL query.
Private Sub btnProcess_Click(sender As Object, e As EventArgs) Handles btnProcess.Click
Dim TestsDT As New DataTable
TestsDT.Columns.Add("SvcAbbrev")
TestsDT.Rows.Add("PH.")
TestsDT.Rows.Add("LCFA")
TestsDT.Rows.Add("FAECALP")
TestsDT.Rows.Add("PE-1")
TestsDT.Rows.Add("BGLUC")
TestsDT.Rows.Add("SIGAF")
TestsDT.Rows.Add("CALP")
TestsDT.Rows.Add("HELPFAE")
TestsDT.Rows.Add("M2-PK")
TestsDT.Rows.Add("FAEZONULIN")
TestsDT.Rows.Add("FAEFAESIGA")
Dim xlApp As Microsoft.Office.Interop.Excel.Application
Dim xlWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim z As Integer
Dim x As Integer
xlApp = New Microsoft.Office.Interop.Excel.Application
xlWorkBook = xlApp.Workbooks.Add(misValue)
For l = 0 To TestsDT.Rows.Count - 1
txtTest.Text = TestsDT.Rows(l).Item("SvcAbbrev")
dgResults.DataSource = GetResults()
Dim Count As Integer = 0
Count = dgResults.Rows.Count - 1
If Count < 1 Then
Else
Dim ChkBox As New DataGridViewCheckBoxColumn()
ChkBox.HeaderText = "Checkbox"
ChkBox.Name = "Check"
dgResults.Columns.Insert(4, ChkBox)
xlWorkSheet = xlWorkBook.Sheets.Add()
xlWorkSheet.Name = txtTest.Text
xlWorkSheet.Columns.AutoFit()
For z = 0 To dgResults.RowCount - 2
For x = 0 To dgResults.ColumnCount - 1
For y As Integer = 1 To dgResults.Columns.Count
xlWorkSheet.Cells(1, y) = dgResults.Columns(y - 1).HeaderText
xlWorkSheet.Cells(z + 2, x + 1) = dgResults(x, z).Value.ToString()
Next
Next
Next
End If
Next
xlWorkBook.Sheets("Sheet1").Delete
xlWorkSheet.SaveAs("C:\Users\brettf\desktop\test-output.xlsx")
xlWorkBook.Close()
xlApp.Quit()
MessageBox.Show("Processing complete. Excel file should open automatically.", "Processing Complete", MessageBoxButtons.OK, MessageBoxIcon.Information)
Process.Start("C:\Users\brettf\desktop\test-output.xlsx")
Current Output:
Desired Output:
The checkbox has no bearing to anything in the datagridview and will be used once the document is printed by another group of staff within the business.

Add Datatable to Existing Excel Spreadsheet vbnet, always Corrupt

UPDATED:
Appeared to be something with the SHEETID, now its finding additional worksheets when working with the USING tag instead in combo with this sheetid finder.
Dim sheetId As UInteger = 1
If (sheets.Elements(Of Sheet).Count > 0) Then
sheetId = CUInt(sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1)
End If
Here is the code i used to make it work, stopped corrupting the file now:
' Given a document name, inserts a new worksheet.
Public Sub InsertWorksheet(ByVal docName As String, ByVal SQL As DataTable, ByVal sheetName As String, ByVal intSheetId As Integer)
'Dim sheetName As String
Dim fileName As String = docName
' Open an existing spreadsheet document for editing.
Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, True)
Using (spreadSheet)
' Add a blank WorksheetPart.
Dim newWorksheetPart As WorksheetPart = spreadSheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
newWorksheetPart.Worksheet = New Worksheet(New SheetData())
' Create a Sheets object.
Dim sheets As Sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)()
Dim relationshipId As String = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart)
' Get a unique ID for the new worksheet.
Dim sheetId As UInteger = 1
If (sheets.Elements(Of Sheet).Count > 0) Then
sheetId = CUInt(sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1)
End If
' Append the new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet
sheet.Id = relationshipId
sheet.SheetId = sheetId
sheet.Name = sheetName
sheets.Append(sheet)
'get the sheetData object so we can add the data table to it
Dim sheetData As SheetData = newWorksheetPart.Worksheet.GetFirstChild(Of SheetData)()
'add the data table
AddDataTable(SQL, sheetData)
'save the workbook
newWorksheetPart.Worksheet.Save()
' Close the document.
spreadSheet.Close()
End Using
End Sub
File is always corrupt after creating, trying to create a spreadsheet with 4 workbooks with separate data loaded via data tables. File size looks to be valid and I dont get any specific errors when creating the file. Just won't open the excel sheet after creating the file.
Existing code to call functions:
Try
CreateExcelFileFromDataTable(iExcelFileLoc & ExportFileName, iAGetTable)
Catch ex As Exception
Dim ExceptionType As Integer = Type.GetTypeCode(ex.GetType())
LogMessage(strAppName & " - Failure : " & iExcelFileLoc & ExportFileName & " Error:'" & ex.Message & "' Error Type:'" & CStr(ExceptionType) & "' Trace:" & ex.StackTrace, TraceEventType.Error)
End Try
Dim iBGetTable As DataTable = GetDataTable(SQL_SELECT_DOCUMENTS_TO_FOR_DOCS_NOT_FOUND_IN_DOCNUMS)
Dim iReportB As String = BuildReportHTML(iBGetTable)
InsertWorksheet(iExcelFileLoc & ExportFileName, iBGetTable, "Missing Scanned Documents", 2)
' ======================================================================
Both functions to create excel initially and then a function to add a new worksheet with datatable to the existing spreadsheet.
Public Sub InsertWorksheet(ByVal docName As String, ByVal SQL As DataTable, ByVal sheetName As String, ByVal intSheetId As Integer)
Dim iFinalSheetName As String = ""
Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
Dim newWorksheetPart As WorksheetPart = spreadSheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
newWorksheetPart.Worksheet = New Worksheet(New SheetData())
' Add Sheets to the Workbook.
Dim sheets As Sheets = spreadSheet.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())
Dim relationshipId As String = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart)
' Append a new worksheet and associate it with the workbook.
Dim sheetId As UInteger = 1
If (sheets.Elements(Of Sheet).Count > 0) Then
sheetId = CUInt(sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1)
End If
iFinalSheetName = (sheetName.ToString())
' Append the new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet
sheet.Id = relationshipId
sheet.SheetId = CType(intSheetId, UInt32Value)
sheet.Name = iFinalSheetName
sheets.Append(sheet)
'get the sheetData object so we can add the data table to it
Dim sheetData As SheetData = newWorksheetPart.Worksheet.GetFirstChild(Of SheetData)()
'add the data table
AddDataTable(SQL, sheetData)
'save the workbook
newWorksheetPart.Worksheet.Save()
' Close the document.
spreadSheet.Close()
End Sub
Public Sub CreateExcelFileFromDataTable(ByVal FilePath As String, myDT As DataTable)
' Create a spreadsheet document by supplying the filepath.
' By default, AutoSave = true, Editable = true, and Type = xlsx.
Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Create(FilePath, SpreadsheetDocumentType.Workbook)
' Add a WorkbookPart to the document.
Dim workbookpart As WorkbookPart = spreadsheetDocument.AddWorkbookPart
workbookpart.Workbook = New Workbook
' Add a WorksheetPart to the WorkbookPart.
Dim worksheetPart As WorksheetPart = workbookpart.AddNewPart(Of WorksheetPart)()
worksheetPart.Worksheet = New Worksheet(New SheetData())
' Add Sheets to the Workbook.
Dim sheets As Sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())
' Append a new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet
sheet.Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart)
sheet.SheetId = 1
sheet.Name = "Duplicate Document"
sheets.Append(sheet)
'get the sheetData object so we can add the data table to it
Dim sheetData As SheetData = worksheetPart.Worksheet.GetFirstChild(Of SheetData)()
'add the data table
'AddDataTable(myDT, sheetData)
'save the workbook
workbookpart.Workbook.Save()
' Close the document.
spreadsheetDocument.Close()
' -----------------------------------
End Sub
Here's an option for you:
Create a sample of the spreadsheet manually.
Download and Install the Open XML SDK tool
Open the spreadsheet in the tool
Once the spreadsheet is opened, there's a section where you can view .NET source code to create a sheet that looks like it.
I use the tool a lot. Working with the Office XML SDK without it can be very cumbersome.

how to write data into the excel sheet without erasing the previous data?

I tried the following code but not work properly.Any type of suggestion will be appreciated
public static void main(String[] args) throws EncryptedDocumentException, InvalidFormatException, IOException {
InputStream inp = new FileInputStream("C:\\Documents and Settings\\Administrator\\Desktop\\Read Data.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(1);
Cell cell = row.getCell(0);
cell.setCellType(cell.CELL_TYPE_STRING);
String cellContents = cell.getStringCellValue();
//Modify the cellContents here
// Write the output to a file
//cell.setCellValue(cellContents);
FileOutputStream fileOut = new FileOutputStream("C:\\Documents and Settings\\Administrator\\Desktop\\Read Data.xlsx");
sheet.createRow(1).createCell(1).setCellValue(cellContents);
wb.write(fileOut);
fileOut.close();
System.out.println(cellContents);
}
You can try this
InputStream inp = new FileInputStream("wb.xls");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt([sheet index]);
Row row = sheet.getRow([row index]);
Cell cell = row.getCell([cell index]);
String cellContents = cell.getStringCellValue();
//Modify the cellContents here
// Write the output to a file
cell.setCellValue(cellContents);
FileOutputStream fileOut = new FileOutputStream("wb.xls");
wb.write(fileOut);
fileOut.close();
Your problem is you are re-creating an existing row, which is wiping out the values already there:
Row row = sheet.getRow(1);
....
sheet.createRow(1).createCell(1).setCellValue(cellContents);
The first call fetches the 2nd row, the second one wipes it and creates a new one
All you need to do is change the second one to re-use the already fetched existing row, and you'll keep the existing values!
Something like (with other fixes....):
DataFormatter formatter = new DataFormatter();
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(1);
Cell cell = row.getCell(0);
String cellContents = formatter.formatCellValue(cell);
//Modify the cellContents here
row.createCell(1).setCellValue(cellContents);
FileOutputStream fileOut = new FileOutputStream("C:\\Documents and Settings\\Administrator\\Desktop\\Read Data.xlsx");
wb.write(fileOut);
fileOut.close();

COM exception while selecting cells in excel with c#

I have a problem selecting a cell in excel using c# while running through a "for" loop.
I have 3 datatables in a dataset(dsReportGrid) which I'm exporting to excel (one sheet per table).
When I try to select a range so I can freeze panes, it goes well in the first iteration of the loop (dsReportGrid.table[0]), but when it gets to second iteration when I try to select the cell in the secondsheet it throws me a COM exception on the select event (the code line with two asterisks).
Why is it happening and how can I handle it?
Thanks,
private void saveXlS()
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range xlCells;
Excel.Range freezeCell;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
for (int table = 0; table <= dsReportGrid.Tables.Count -1; table++)
{
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(table +1);
Excel.Range k = xlWorkSheet.get_Range("a2");
**k.Select();**
k.Application.ActiveWindow.FreezePanes = true;
break;
}
...rest of code writing from dataset to excel
}
Try activating the worksheet before attempting to select the range. I think you can only select a range on an active worksheet.

Resources