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...
Related
I am trying to build simple program that does my weekly job.
Everytime I receive csv file, I maintain excel file.
My csv is like below:
key_code,eng_name,...so on
000001,some name,...so on
My excel is like below:
Some text are written on A1-G4
No column hearders written
Data is from 5th row
Each row has data from B-G(1st row B5-G5, 2nd row B6-G6)
If key_code in csv does not exist in excel, I add.
If key_code in csv does exist in excel, I update the rest columns.
If key_code in excel does not exist in csv, I delete the row.
Can anyone tell me any easy way or steps to get this done?
I am very confusing about what to use to update excel file among OleDb, Interop.Excel, epplus, spire.xls, etc.
And in which class do I have to store csv data and excel data to compare.
For reading CSV you can use ChoETL reader, this is one of the best CSV readers I have ever used.
The tricky part is to how to write Excel file and choosing the right tool, amongst the tools you have mentioned EPPlus is best because
Excel.Interop needs Excel(MS Office) to be installed on production machine which can create licencing issues
To use OleDB you need some nitty gritty to use it a better way
EPPlus provides some abstraction which makes it easy to manipulate the excel files
using (var p = new ExcelPackage())
{
//A workbook must have at least on cell, so lets add one...
var ws=p.Workbook.Worksheets.Add("MySheet");
//To set values in the spreadsheet use the Cells indexer.
ws.Cells["A1"].Value = "This is cell A1";
//Save the new workbook. We haven't specified the filename so use the Save as method.
p.SaveAs(new FileInfo(#"c:\workbooks\myworkbook.xlsx"));
}
This is very simple example given on the github page to write, please use it and post any specific issues
If key_code in csv does not exist in excel, I add.
If key_code in csv does exist in excel, I update the rest columns.
If key_code in excel does not exist in csv, I delete the row.
As my understanding of the rules above, you simply delete the old excel file and create a new file from the data in the CSV file.
You can use R to do this very easily:
#Install package 'writexl' if you didn't, by install.packages("writexl")
library(writexl)
#File excel
fn <- "file.xlsx"
#Check its existence
if (file.exists(fn))
#Delete file if it exists
file.remove(fn)
#Read the csv file to a data frame
df <- read.csv("C:/newfile.csv")
#Write the data frame to excel file. Change col_names = TRUE if you want the headers.
write_xlsx(
df,
path = "file.xlsx",
col_names = FALSE
)
So I am new to Oledb and I a have project that requires me to grab data from an excel file using a Console Application. The excel file has around 500 columns and 55 rows. How could I possibly get data from columns past 255?
In order to read columns 256 -> you just need to modify the Select statement. By default both the Microsoft.ACE.OLEDB.12.0 and the Microsoft.Jet.OLEDB.4.0 drivers will read from Column 1-255 (A->IU) but you can ask it to read the remaining columns by specifying them on the Select statement.
To read the next 255 columns and taking "Sheet1" as your sheet name you would specify...
Select * From [Sheet1$IV:SP]
This will work even if there aren't another 255 columns. It will simply return the next chunk of columns if there are 1...255 additional columns.
Incidentally, the Microsoft.ACE.OLEDB.12.0 driver will read both .xls and any variant of .xlsx, .xlsm etc without changing the extended properties from "Excel 12.0". There is no need to if...then...else the connection string depending on the file type.
The OLEDB driver is pretty good for the most part but it really does rely on well formed sheets. Mixed data types aren't handled terribly well and it does weird things if the first columns/rows are empty but aside from that it's fine. I use it a lot.
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.
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