QT Excel - Open to Read/Write - excel

I'd like to know what's the best way to open excel file (.xlsx) (Need to write and read or eventually only read)
I've already tried this (it's only test):
void MainWindow::openExcel()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "xls_connection");
db.setDatabaseName("DRIVER={Microsoft Excel Driver (*.xls,*.xlsx,*.xlsm,*.xlsb)};DBQ=" + QString ("C:\\Users\\User\\Desktop\\file.xlsx") );
if(db.open())
{
QSqlQuery query("select * from [" + QString("Sheet1") + "$A1:B5]");
while (query.next())
{
//reading columns
QString column1= query.value(0).toString();
qDebug()<<column1;
}
db.close();
QSqlDatabase::removeDatabase("xls_connection");
}
else
{
qDebug()<<"Failed";
}
}
but it couldn't open such file ("Failed"). I would be glad if anyone could say where's a problem
//Maybe also recommend any good books or tutorials for QT?

To use ODBC for Excel on Windows, the MS Access Database Engine must be downloaded as mentioned in the wiki Note from which this sample code was tested (Win7/ qt4.9 , Win10/ qt 5.7) , then the connection can work. alternatively in the same Qt wiki Content, you can find different ways of opening MS Excel with Qt.

You can use ActivX object to work with excel file -
ActiveX Excel example
Other option to read-write into excel file format (.xlsx) -
QtXlsxWriter

Related

Error accessing Names in Excel using Interop

I am programming an application in C# (Visual Studio 2015) and I need to update an .xlsm file.
This file has many formulas, over 1200 names and vba code.
I am using the Interop library and I am able to update some cells and get the relative updated formulas but i have some problem with the Names defined in the Excel.
The program recognizes the names in the Names collection but doesnt let me access some of the names.
When I try to access the value of the cell using its name it produces an exception.
I dont understand why i can access some of the names and others no.
Besides, in the excel, I can see the Name in the combo but when I select it, the cursor doesn't position over the cell.
In my program I could avoid this problem accessing the cells using the reference instead of the Name, but the vba in the excel uses the names and if i open the file from my app it doesnt work.
I am using this code:
excelApplication = new Microsoft.Office.Interop.Excel.Application();
excelApplication.ScreenUpdating = true;
excelApplication.Visible = true;
excelApplication.DisplayAlerts = false;
excelWorkbook = excelApplication.Workbooks.Open(txtFicheroEntrada.Text);
wsDatos = excelWorkbook.Worksheets[1];
wsDatos.Select();
foreach(Microsoft.Office.Interop.Excel.Name v in excelWorkbook.Names)
{
string NombreVar = v.Name;
//here i found the name BobinadoAT correctly. It exists
if (NombreVar == "BobinadoAT" ){ Console.WriteLine(NombreVar); }
}
if (wsDatos.Range["BobinadoAT"] != null) //but here this produces an exception
{
string valorcelda = wsDatos.Range["BobinadoAT"].Value.ToString();
}
¿does anyone work with many excel Names?
¿Am I accessing the names incorrectly?

MFC How do I get the excel 2007 driver, to prevent the limit of 65536 rows

Use MFC to insert data to excel 2003, I found the limit of 65536 rows,
I don't want to create another sheet to save data, so I want use excel 2007,
which extension is .xlsx.
I use follow code to get driver
((CDR12Dlg*)AfxGetMainWnd())->sExcelDriver = _T("MICROSOFT EXCEL DRIVER (*.xls)");
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelFilePath.Format(((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strBaseFolder);
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelFilePath.AppendFormat(_T("%s_%s_%.0f℃_%d%s"),
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strDevID,
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strDevModel,
theApp.fTab1TestAvgTemp,
loop,
_T(".xls"));
TRY
{
// Build the creation string for access without DSN
strSql.Format(_T("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=/%s/;DBQ=%s"),
((CDR12Dlg*)AfxGetMainWnd())->sExcelDriver,
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelFilePath,
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelFilePath);
// Create the database (i.e. Excel sheet)
if( ((CDR12Dlg*)AfxGetMainWnd())->database.OpenEx(strSql,CDatabase::noOdbcDialog) )
{
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelTableName.Empty();
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelTableName.Format(_T("%s_%s"),
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strDevID,
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strDevModel);
CString strSqlField;
strSqlField.Format(_T("RecvTime TEXT,"));
for(int loop=1; loop<=theApp.nTab1TestPointNumber; loop++)
{
if(loop == theApp.nTab1TestPointNumber)
{
strSqlField.AppendFormat(_T("TestPoint%d NUMBER"), loop);
} else {
strSqlField.AppendFormat(_T("TestPoint%d NUMBER,"), loop);
}
}
// Create table structure
strSql.Format(_T("CREATE TABLE \"%s\" (%s)"),
((CDR12Dlg*)AfxGetMainWnd())->sTab1CurveFile.strExcelTableName,
strSqlField);
((CDR12Dlg*)AfxGetMainWnd())->database.ExecuteSQL(strSql);
}
// Close database
((CDR12Dlg*)AfxGetMainWnd())->database.Close();
}
CATCH_ALL(e)
{
TRACE1("Driver not installed: %s\n",((CDR12Dlg*)AfxGetMainWnd())->sExcelDriver);
}
END_CATCH_ALL;
Ok, above code is work well in Excel 2003, but I change the code from .
sExcelDriver = _T("MICROSOFT EXCEL DRIVER (*.xls)");
replace
sExcelDriver = _T("MICROSOFT EXCEL DRIVER (*.xlsx)");
or
sExcelDriver = _T("MICROSOFT EXCEL DRIVER (*.xls, xlsx)");
and save as .xlsx file
but the result will show me "Driver not installed"
I have try to install the AccessDatabaseEngine, which link the excel 2007,
how do I change the code to acces excel 2007 file.
OK, I find the solution,
In windows7 control panel->system menage tool->data source(ODBC)
select the "user data source name" of tab
find the Excel file field, and the sExcelDriver CString in the code,
Must match the driver string include blank and length.
as follow code
sExcelDriver = _T("MICROSOFT EXCEL DRIVER (*.xls, *.xlsx, *.xlsm, *.xlsb)");

Convert CSV to Excel Windows Phone 8

with windows phone 8 I need to be able to open a CSV file in Excel using C#. Their is an app on the market now called Excel Extensions that converts the csv file locally.
I have tired converting the CSV file using open office XML but that didn't work. and I want to do it locally so no web services.
Anyone know how I can convert the CSV file to Excel on the Windows Phone 8 platform?
THEORY
You have a two distinct options: (1) doing most of the work on the WP8 client (2) or doing most of the work on a remote server.
For option #2 of using a remote server: Expose a WCF service that takes in the CSV file, parses the CSV to find its logical 2D table structure, use ClosedXML to save a new XLSX file and return that to the client. This option is the most straightforward but also requires network connectivity and a hosted server.
For option #1 of not using a remote server: read the CSV file, copy the CSV data into to an XLSX file, save the XLSX into IsoStore and launch excel with that file. I've written about this topic in the past # How can we create, write and read an excel file for Windows Phone 8
One thing you'll have to do quite a lot of work is writing a XLSX file in pure WP7 C#. You'll either have to convert 3rd party libraries that write XLSX to support WP7/WP8, or convert simple end-to-end C# code samples to WP7/WP8. Both aren't simple. Converting ClosedXML is possible but DocumentFormat.OpenXml's dependency on WPF's WindowsCore is a problem. Another option is to write your own OpenXML C# implementation like Chris Klug did here for Word OpenXML on Silverlight and was ported to WP7 later on. The key is using OpenXML specification for your advantage.
LIVE CODE SAMPLE
For example, looking at Chris Klug's Silverlight Excel OpenXML article it's possible to take his code for Ag.OpenXML and OpenXML.Silverlight.Spreadsheet port those to WP8 and then simply invoke them. I did just that. Here's how to get that experimental source code and get started:
1) Download and unzip # http://JustinAngel.net/Storage/OpenXML.Silverlight.Spreadsheet.WP8.zip
2) Add a reference to the csproj, or to the DLLs OpenXML.Silverlight.Spreadsheet.WP8.dll & SharpZipLib.dll from "OpenXML.Silverlight.Spreadsheet.WP8\Bin\Debug".
3) Add the following code snippet that saves a SpreedsheetDocument file into your app's WP8 IsoStore and then launches it in Word using WP8 app2app file associations.
private async void SaveXlsxToIsoStoreAndLaunchInExcel(SpreadsheetDocument doc)
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists("myFile.xlsx"))
isoStore.DeleteFile("myFile.xlsx");
using (var s = isoStore.CreateFile("myFile.xlsx"))
using (IStreamProvider storage = new ZipStreamProvider(s))
{
doc.Save(storage);
}
Launcher.LaunchFileAsync(
await ApplicationData.Current.LocalFolder.GetFileAsync("myFile.xlsx"));
}
}
4) Invoke the above code snippet with Chris's sample document:
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
SpreadsheetDocument doc = new SpreadsheetDocument();
doc.ApplicationName = "SilverSpreadsheet";
doc.Creator = "Chris Klug";
doc.Company = "Intergen";
SharedStringDefinition str1 = doc.Workbook.SharedStrings.AddString("Column 1");
SharedStringDefinition str2 = doc.Workbook.SharedStrings.AddString("Column 2");
SharedStringDefinition str3 = doc.Workbook.SharedStrings.AddString("Column 3");
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[0].SetValue(str1);
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[1].SetValue(str2);
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[2].SetValue(str3);
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[0].SetValue("Value 1");
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[1].SetValue(1);
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[2].SetValue(1001);
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[0].SetValue("Value 2");
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[1].SetValue(2);
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[2].SetValue(1002);
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[0].SetValue("Value 3");
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[1].SetValue(3);
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[2].SetValue(1003);
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[0].SetValue("Value 4");
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[1].SetValue(4);
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2].SetValue(1004);
TablePart table = doc.Workbook.Sheets[0].Sheet.AddTable("My Table", "My Table", doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[0], doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2]);
table.TableColumns[0].Name = str1.String;
table.TableColumns[1].Name = str2.String;
table.TableColumns[2].Name = str3.String;
doc.Workbook.Sheets[0].Sheet.AddColumnSizeDefinition(0, 2, 20);
doc.Workbook.Sheets[0].Sheet.Rows[5].Cells[1].SetValue("Sum:");
doc.Workbook.Sheets[0].Sheet.Rows[5].Cells[2].Formula = "SUM(" + doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[2].CellName + ":" + doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2].CellName + ")";
SaveXlsxToIsoStoreAndLaunchInExcel(doc);
}
5) When running this code snippet we can see the following warning popup and then the excel spreadsheet. Feel free to improve upon my hasty Silverlight-->WP8 port and remove that warning.

Excel process stays alive even after calling Quit

I am creating Excel Sheet using Devexpress Exporter and then saving the file at a particular location.
After the creation of file, I have to open it, to add dropdownlist of items and then save it again in same location.
After all the operations, the file has to be emailed automatically to the email address from database.
Now if I have 1000 email addresses, and to automate this process, it is creating more than 10 instances of Excel.
How can I stop creation of those instance and how can I use excel operations without using more memory.
Code is as below:
protected string CreateExcelFile(string FilterName)
{
Random ranNumber = new Random();
int number = ranNumber.Next(0, 10000000);
string FileName = "TestDoc"+DateTime.Now.Year.ToString()+number.ToString()+DateTime.Now.Second.ToString()+".xls";
string path = #"c:\TestDocuments\"+FileName;
Directory.CreateDirectory(Path.GetDirectoryName(path));
FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
XlsExportOptions options = new XlsExportOptions();
options.ExportHyperlinks = false;
ASPxExporter.WriteXls(fs, options);
fs.Close();
AddDropDownToExcel(path);
return path;
}
//Adding The Dropdownlist Of Items TO Generated Excel Sheet
protected void AddDropDownToExcel(string path)
{
Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
string fileName = path.Replace("\\", "\\\\");
string RowCount = "F" + (testgrid.VisibleRowCount + 1).ToString();
// Open Excel and get first worksheet.
var workbook = application.Workbooks.Open(fileName);
var worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;
// Set range for dropdownlist
var rangeNewStatus = worksheet.get_Range("F2", RowCount);
rangeNewStatus.ColumnWidth = 20;
rangeNewStatus.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList, Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop,
Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween, "Item1,Item2,Item3,Item4");
// Save.
workbook.Save();
workbook.Close(Microsoft.Office.Interop.Excel.XlSaveAction.xlSaveChanges, Type.Missing, Type.Missing);
application.Quit();
}
First, I sincerely hope this isn't running on a server.
Then, if your problem is that too many instances of Excel are created, a thought is "don't create an instance every single time". Instead of starting Excel every time AddDropDownToExcel is called, can you reuse the same instance?
The problem you are having shows up regularly in Excel interop scenario; even though you are done and tell Excel to close, it "stays alive". It's usually caused by your app still holding a reference to a COM object that hasn't been disposed, preventing Excel from closing. This StackOverflow answer provides some pointers: https://stackoverflow.com/a/158752/114519
In general, to avoid that problem, you want to follow the "one-dot" rule. For instance, in your code:
var workbook = application.Workbooks.Open(fileName);
will be a problem, because an "anonymous" wrapper for Workbooks is created, and will likely not be disposed properly. The "one-dot" rule would say "don't use more than one dot when working with Excel interop", in this case:
var workbooks = application.Workbooks;
var workbook = workbooks.Open(fileName);
A totally different thought - instead of using Interop, can't you use OpenXML to generate your Excel file? I have never tried it to create drop downs, but if it supports it, it will be massively faster than Interop, and the type of problems you have won't happen.
Hope this helps.
As I know the grow of number of runnig excel.exe processes is 'normal' situation to excel :)
The dumbest advice is just kill sometimes it's processes. BUT, this way will be absolutely unhelpful if you use excel during your app is working because of you rather don't get which one excel.exe is yours.

How can I programatically convert .xls and .csv files to .xlsx?

Is there a programmatic solution to this that does not involve having Office on the server?
Update:
This solution will be deployed in a .Net shop, so for now PHP and Java approaches aren't on the table (though I was impressed with the libraries themselves).
We will be receiving documents in csv, .xls, and .xlsx formats that need to be parsed and their data shoved into a DB. We're planning on using the OpenXML SDK for all of the parsing goodness and want to operate over only one file type.
You can achieve this using the Apache POI library for Java.
HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format.
XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.
I've used it to read in a complete mix of .xls and .xlsx files, and I always output .xlsx.
For .csv files, import using the Super CSV library and export using the Apache POI library above.
The main motivation for Super Csv is to be the best, fastest and most programmer friendly free CSV package for Java.
Or use PHPExcel ( http://www.phpexcel.net ) if you want a PHP solution rather than java
For csv files i would recommend a combination of http://kbcsv.codeplex.com/ to read the csv file into a datatable and EPPPLUS to use its .FromDataTable Method to convert it to an xlsx file.
I works great for me and is very fast.
For reading xls files there is no free Implementation that I know of :(
and you can use for parse columns.
object columnValue = ws.Cells[i, ColIndex, i, ColIndex].Value; // get Specific cell.
you can use below method for .csv, xlsx, .txt files.
public yourReturnType compute()
{
#region .XLSX Section
if (FilePath.FullName.Contains(".xlsx") || FilePath.FullName.Contains(".xls"))
{
// Open and read the XlSX file.
using (var package = new ExcelPackage(FilePath))
{
ExcelWorkbook wb = package.Workbook; // Get the work book in the file
if (wb != null)
{
if (wb.Worksheets.Count > 0)
{
ExcelWorksheet ws = wb.Worksheets.First(); // Get the first worksheet
yourParseCode(ws);
}
} // if End.
} // using end.
}
#endregion
#region .CSV Section
if (FilePath.FullName.Contains(".csv") || FilePath.FullName.Contains(".txt"))
{
CSVParser c = new CSVParser(FilePath);
DataTable dt = c.ReadCSVFile();
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("temporary");
ws.Cells["A1"].LoadFromDataTable(dt, true);
yourParseCode (ws);
////pck.Save(); // no need to save this temporary sheet.
}
}
#endregion
return (yourReturnType );
}

Resources