With ClosedXML I am trying to add data to an existing Excel Sheet In an Existing Table. The easy thing to do is to add a table to an excel sheet below is a quick example of how to do that. What I don't understand is if you already have a Table there that is empty how can you just add to the existing table?
// Add a DataTable as a worksheet
wb.Worksheets.Add(dataTable);
I don't know how this question isn't clear to people. If there is an existing Table (created in Excel by going to "Insert -> Table") and you open an Excel document using ClosedXML, adding data to the next row does not automatically expand the Table.
You can expand it prior to adding the data as such:
IXLTables tsTables = thisSheet.Tables;
IXLTable firstTable = tsTables.FirstOrDefault();
if (firstTable != null)
firstTable.InsertRowsBelow(1);
I had a similar requirement, where I needed to insert data into an existing Table, which had a number of data validations / comments / formula built in.
I found that the easiest solution (for me) was to use the Table's ReplaceData call. This is particularly useful if you provide a name for your Table in the Excel worksheet, as that way you can get a reference to the table directly from the workbook, ie:
var candidateTable = workbook.Table("Candidates");
candidateTable.ReplaceData(candidateData, propagateExtraColumns: true);
Note that the key to getting this to work properly is to set the propogateExtraColumns parameter - this will ensure any formula / etc you have set will automatically be copied to any new rows that are created.
FYI - you can set the Excel Table's name by selecting your table in the worksheet, clicking the Design tab, and then entering a table name:
To add a DataTable to an existing worksheet use this:
wb.Worksheet(1).Cell(1, 1).InsertTable(dataTable);
More info in the documentation.
Related
I create xls/xlsx file from C# using ODBC (with Provider=Microsoft.ACE.OLEDB.12.0). The result table has 4 rows (for example). I open the file with Excel, add 5-th row and save the file. When try to read it from C# over ODBC with SELECT * FROM [table] I get only the original 4 rows without 5th. It seems ODBC stores somewhere in XLS file the number of rows and later reads only them without new data entered from Excel or LibreOffice. Is this known problem and can I solve it? If I create new spreadsheet in Excel, all its rows are read fron C#.
EDIT: I found some useful information. When the XLS file is first created from C#/ODBC, there are 2 tables (sheets). If the table name is TABLE, DataTable sheets = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null) will contain sheets.Rows[0] == "TABLE" and sheets.Rows[1] == "TABLE$". Excel will show only one sheet "TABLE". After edit the changes (5th row) exist only in "TABLE$" sheet.
Are you adding the 5th row by code if yes, could you please share the code lines which you are using for doing the same. There might be following issue in your code.
Save commit not done properly.
Before reading the file connection refresh not done.
I think I found the problem. It seems that internal spreadsheet names created by Excel have "$" sign at the end. The sheet name generated by ODBC are the exact string given in CREATE TABLE. On the other hand, Excel (and LibreOffice) show only one sheet for both TABLE and TABLE$ sheets. If I edit the table in Excel, after save the changes are only in TABLE$. The other sheet TABLE is unchanged. When I do SELECT * FROM [TABLE] the result is from the original ODBC generated table without Excel changes. Now I enumerate the available sheets inside XLS file and if first sheet name does not end with "$" and sheets are more than 1, I add "$" to first sheet name and open the correct table. I suppose ODBC connection string may include option to work with "$"-ending tables...
Can is possibility create Excel document without placed inside spreedsheet the base table? Or at least that base table was in other worksheet than pivot table.
Currently I create DataColumn, after add row and...
ExcelWorksheet worksheet = pkg.Workbook.Worksheets.Add("Table");
worksheet.Cells["A1"].LoadFromDataTable(table, true);
var pivotTable = worksheet.PivotTables.Add(worksheet.Cells["H14"],
worksheet.Cells[rangePivotTable], "pivTable");
pivotTable.RowFields.Add(pivotTable.Fields["Grid"]);
.
.
.
It seems that EPPlus PivotTable can be created only from the data that is already present in the workbook; so you have to place source table into the spreadsheet.
Good news is that you can easily have pivot table and base table in the different worksheets:
var wsPvt = pkg.Workbook.Worksheets.Add( "Pivot Table" );
var wsData = pkg.Workbook.Worksheets.Add( "Source Data" );
var rangePivotTable = wsData.Cells["A1"].LoadFromDataTable( tbl, true );
var pivotTable = wsPvt.PivotTables.Add(
ws.Cells[1,1],
rangePivotTable, "pvtTable");
I assume that you don't want to place base table into spreadsheet because it is either rather big or just contain sensitive details. In this case you may aggregate base table with C# code (group it by columns that used for pivot table rows and columns) and use grouped result as base table for Excel Pivot Table. Aggregation may be simply performed with PivotData library -- let me know if you're interested in this way and need more explanations (I'm an author of this library).
Absolutely! Just set the data source of the pivot table using PivotTable.SourceData to specify a connection string.
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.pivottable.sourcedata.aspx
A little different way to do it, that works for me, is as follows:
var dataRange = rawDataWorksheet.Cells[rawDataWorksheet.Dimension.Address];
var pivotTable =
pivotTableWorksheet.PivotTables.Add(pivotTableWorksheet.Cells["A6"]
dataRange, "PivotTable");
"rawDataWorksheet" is the sheet that contains the source data; "pivotTableWorksheet" is the sheet on which you want to plop the PivotTable. In the code above, it starts at the intersection of column A (1) and row 6, but you could use another target cell, of course.
I have created a package that will query SQL server and return results to excel, this package should replace existing data on the excel with new data every time it runs.
But Drop table command only clears the headings of excel table not the previous data.
Its appending new data in sheet not deleting the old data.
Drop table I am using this command.
Drop Table `Report`
Go
Create Table :
CREATE TABLE `Report` (
`EmployeeID` Long,
`EmpName` LongText,
`EmpGrp` LongText
)
GO
Please help on this. How to delete data from table in excel.
You can create a template file containing the sheet with the header and a File System Task copies it over the previously exported file before the Data Flow Transformation.
Maybe this solution will suit your needs: Overwrite Excel File in SSIS: Workaround for Excel Connection Manager
One way could be to use 'Script Task' in place of Drop Table to validate if the excel is already present and if yes then delete the existing excel.
`
(File.Exists(Dts.Variables["User::DestinationExcelFilePath"].Value.ToString()))
{
File.Delete(Dts.Variables["User::DestinationExcelFilePath"].Value.ToString());
}
Dts.TaskResult = (int)ScriptResults.Success;
`if
Rest all follow the same process as you are doing right now. Also please note to set DelayValidation property of Control Flow to True for the code to work as expected.
I need to take values form one sheet in one Excel workbook and insert them into another existing workbook.
The values I need to take are the first 6 columns of the first file:
And I want to insert them at the beginning of another book like so
I've been using Spire.Xls to read values from the first sheet and I thought I could just do the same; parse the worksheet, read the values and just paste them into the other sheet, but that wouldn't work because three of the columns I want to copy have the same header "Descripcion" so my parser would only take the values form the first descripcion column and skip the other ones.
Is there any way, using Excel.Interop or maybe Spire itself to copy and paste entire columns between workbooks? Or alternately, is there any way to get all of the 3 "descripcion" values (without rewriting the title of the columns)?
VSTO might be helpful. I've done similar tasks in C#/VSTO.
Perhaps read through: Simple Example of VSTO Excel using a worksheet as a datasource
I am making an add-in and I am trying to format the output which my add-in generates,using Format as table table-styles provided by Excel.
The one which you get on the 'home tab' --> 'Format as Table' button on the ribbon.
I am using following code:
SourceRange.Worksheet.ListObjects.Add(XlListObjectSourceType.xlSrcRange,
SourceRange, System.Type.Missing, xlYesNo, System.Type.Missing).Name =
TableName;
SourceRange.Select();
SourceRange.Worksheet.ListObjects[TableName].TableStyle = TableStyleName;
TableStyleName is any style name like TableStyleMedium17, you get it if you just hover a particular style in Excel.
My problem is that, even if I keep the SourceRange as 10 columns, all the columns right till the end get selected and are considered as one table.
Because of that the table I populate right next to it is also considered as a part of the first table that was generated.Since, both the table have same column names excel automatically changes the column names in all the following tables that are generated.
Also, because I am generating the tables in a loop after 2 tables are generated I get the error :
A table cannot overlap another table.
PS: I am clearly mentioning SourceRange as:
var startCell = (Range)worksheet.Cells[startRow, startCol];
var endCell = (Range)worksheet.Cells[endRow, endCol];
var SourceRange = worksheet.get_Range(startCell, endCell);
Kindly suggest a way out.
We were able to figure out what was happening on our end for this:
on the
xlWorkbook.Worksheets.Add([before],[after], Type.Missing, Type.Missing)
call, we had to flip before and after since we wanted the sheets to move right, not left and then accessed
xlWorkbook.Worksheets[sheetCount]
by increasing sheetcount for however many sheets were being generated.
Having it the other way was creating the worksheet to access a previously assigned table formatfrom the SourceRange.Worksheet.ListObjects[TableName].TableStyle = TableStyleName call.
So, I got around this problem a week after posting this, sorry did not update in the rush of things.
This actually is an in built excel functionality.
You cant help it, the excel application will keep doing this.
So, ultimately wrote my own table styles in c# and applied it to the excel range which is mentioned as SourceRange. Its just like writing CSS.
If you are interested in knowing the details of that comment it on this question itself or you can contact me by email from my profile.