excel interop saveas not working - c#

I have the following code for creating and saving an excel file in c# but when it finishes, no file is created to my desktop, I can't figure out what I'm doing wrong:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.Visible = false;
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet ws = (Worksheet)wb.Worksheets[1];
Range rangeAToC = ws.get_Range("A1", "C1");
string[] headerRow = { "GIP Id", "First Name", "Last Name"};
int indexAtRow = 0;
foreach (Range cell in rangeAToC)
{
cell.Value2 = headerRow[indexAtRow];
indexAtRow++;
}
//Save report
wb.SaveAs("C:/Users/Abdul/Desktop/GipEmployeeReport.xls", Type.Missing,
Type.Missing,Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
//Close out COM objects
xlApp.Workbooks.Close();
xlApp.Quit();

first thing i noticed is that your using forward slashes (/) instead of backslashes \

Related

Add the option "automatic return" to my cells C#

i want to add the option "automatic return" (in french "retour automatique à la ligne") to all actives cells in my Excel file.
For now i have try a lot of things but i can't find this option...
Can you maybe help me? Here is what i have:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application app = new Excel.Application();
wb = app.Workbooks.Open(PathWrite.Replace(".csv", ".xlsx"), Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing);
Excel._Worksheet workSheet = app.ActiveSheet;
for (int x = 1; x <= 7; x++)
{
Excel.Range range = workSheet.Columns[x];
range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
workSheet.Columns.UseStandardWidth = 30;
Excel.Borders border = range.Borders;
border.LineStyle = Excel.XlLineStyle.xlContinuous;
border.Weight = Excel.XlBorderWeight.xlThin;
border.ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic;
range.AutoFit();
}
For resume, i want to format a file that i created by converting a .csv file into .xlsx file. I'm not used to Office Interop so don't hesitate to tell me if something is bad and the reason for having this disgusting for loop is that i don't succeed to select only the 7 first columns with one command.. It's only my second day working on Excel by C# so be indulgent please. For my language too i think, i'm not really good with english.
Thanks for reading this
I believe the setting you want is word wrap:
range.WrapText = True

Copy an Excel sheet to new sheet including formatting - C#

I need to create one method that it's able to copy an excel sheet and then, paste it on a new excel sheet in the same workbook, but it's necessary to copy the formatting as well.
I found several codes, but all of them not copy the formatting, only the text.
below the code that I wrote:
// Opening Excel File
Microsoft.Office.Interop.Excel.Application excel = null;
excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(file, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Sheets sheets = workbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(1);
Microsoft.Office.Interop.Excel.Worksheet sheet2 = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(2);
// Copy the source sheet
Object defaultArg = Type.Missing;
sheet = (Worksheet)workbook.Sheets[1];
sheet.UsedRange.Copy(defaultArg);
// Paste on destination sheet
sheet2.UsedRange._PasteSpecial(XlPasteType.xlPasteValues, XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
workbook.Save();
common.closeExcel(excel, workbook);
If anybody has any suggestion, please let me know.
Thanks,
This will make an exact copy of a sheet to a new sheet renamed as the original :
Dim x = 2
For numtimes = 1 To x
Sheet1.Copy _
After:=Sheet1
Next

Low performance when reading data from Excel workbook to ArrayList in C#

Here's a problem description.
CONDITIONS:
General idea is to read a lot of real numbers from MS Excel file and put them inro ArrayList for further processing.
An excel workbook has only one worksheet. All the numbers are real and they are stored in one column.
I read these numbers row by row and put them into ArrayList.
PROBLEM: the process takes too much time. Program spends about 2 minutes to fill an ArrayList with 10000 elements.
Here's my code. I need your advise to make it faster. But the structure of the file cannot be modified. It's only possible to modify code.
Help me please to make it faster.
// Method GetExcelData opens 1 excel file, reads data row by row and adds
// it into the array of source Data Values (sourceDataValues in our case).
private void GetExcelData(string fullPath, ArrayList arrForValues)
{
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Excel.Worksheet excelworksheet = (Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Excel.Range excelcells = excelworksheet.UsedRange;
uint rowsNum = 0;
for (rowsNum = 1; rowsNum != excelcells.Rows.Count; rowsNum++)
{
arrForValues.Add((excelcells.Cells[rowsNum, 1] as Excel.Range).Value2);
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
The problem is resolved.
Everything is qute simple. First, we read all the range of current worksheet into simple two-dimension array - worksheetValuesArray. After that we put all the values from that array into our container, converting the type of elements to double. Here's the part of corrected solution:
private void GetExcelData(string fullPath, List<double> arrForValues)
{
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Excel.Worksheet excelworksheet = (Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Excel.Range excelcells = excelworksheet.UsedRange;
object[,] worksheetValuesArray = excelcells.get_Value(Type.Missing);
for (int col = 1; col < (worksheetValuesArray.GetLength(1)+1); col++)
{
for (int row = 1; row < (worksheetValuesArray.GetLength(0)+1); row++)
{
arrForValues.Add((double) worksheetValuesArray[row, col]);
}
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
My experience with Excel automation is that it is always slow. I usually try an alternative method, such as saving it as a CSV and reading the data with a stream reader and splitting the string on a delimiter (comma, tab, etc). I would suggest looking at the process of receiving your data and see if there is another format readily available.
I tweaked the for loop. See if this yields better results.
// Method GetExcelData opens 1 excel file, reads data row by row and adds
// it into the array of source Data Values (sourceDataValues in our case).
private void GetExcelData(string fullPath, ArrayList arrForValues)
{
Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Microsoft.Office.Interop.Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet excelworksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Microsoft.Office.Interop.Excel.Range excelcells = excelworksheet.UsedRange;
Microsoft.Office.Interop.Excel.Range newRange = excelworksheet.get_Range("A1","A"+excelcells.Rows.Count);
object[,] items = newRange.Value;
for (int i = 1; i < items.Length; i++)
{
arrForValues.Add(items[i,1]);
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
I don't know if you're gonna find much more performance. Excel interop is just slow (due to marshaling across COM boundaries I assume). I have gained some performance in my code (especially in Excel 2007 and higher) by setting the following.
excelapp.ScreenUpdating = false;
and
excelapp.Calculation = Excel.XlCalculation.xlCalculationManual;

Excel automation using C#

I have a folder with close to 400 excel files. I need to copy the worksheets in all these excel files to a single excel file.
using Interop and Reflection namespaces heres is what I have accomplished so far.
I use folderBrowserDialog to browse to the folder and select it, this enable me to get the file names of the files within the folder and iterate through them this is as far as i got, any help would be appreciated.
if (result == DialogResult.OK)
{
string path = fbd1.SelectedPath; //get the path
int pathLength = path.Length + 1;
string[] files = Directory.GetFiles(fbd1.SelectedPath);// getting the names of files in that folder
foreach (string i in files)
{
MessageBox.Show("1 " + i);
myExcel.Application excelApp = new myExcel.ApplicationClass();
excelApp.Visible = false;
MessageBox.Show("2 " + i);
myExcel.Workbook excelWorkbook = excelApp.Workbooks.Add(excelApp.Workbooks._Open(i, 0, false, 5, "", "", false, myExcel.XlPlatform.xlWindows, "", true, false, 0, true));
myExcel.Sheets excelSheets = excelWorkbook.Worksheets;
MessageBox.Show("3 " + i);
excelApp.Workbooks.Close();
excelApp.Quit();
}
MessageBox.Show("Done!");
}
How do i append the copied sheets to the destination file. Hope the question is clear?
thanks.
use Worksheet.Copy(Before, After) and specify after as the last worksheet of whatever main file you want. Please note you might need to create a new worksheet in the mainApp so that it has a worksheet to input after so that it doesn't throw an exception.
Try the following:
Excel.Application mainApp = new Excel.ApplicationClass();
mainApp.Visible = false;
Excel.Workbook mainWorkbook = excelApp.Workbooks.Add(null);
Excel.Sheets mainWorkSheets = mainWorkbook.Worksheets;
foreach (string i in files)
{
MessageBox.Show("1 " + i);
Excel.Application exApp = new Excel.ApplicationClass();
exApp.Visible = false;
MessageBox.Show("2 " + i);
Excel.Workbook exWorkbook = exApp.Workbooks.Open(i,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
MessageBox.Show("3 " + i);
foreach(Excel.Worksheet sheet in exWorkbook.Worksheets)
{
sheet.Copy(Type.Missing, mainWorkSheets[mainWorkSheets.Count -1]);
}
}
mainApp.Save("NewExcel");
How about something like: Merge(#"C:\ExcelFolder", #"C:\FinalDestination.xls"); works for me, directly outta working sample - trimmed for you.
Hopefully, you wont require any tweaks but in case you do, then do (0:
Please see following code:
private void Merge(string strSourceFolder, string strDestinationFile)
{
try
{
//1. Validate folder,
//2. Instantiate excel object
//3. Loop through the files
//4. Add sheets
//5. Save and enjoy!
object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
ExcelApp.Visible = false;
//Create destination object
Microsoft.Office.Interop.Excel.Workbook objBookDest = ExcelApp.Workbooks.Add(missing);
foreach (string filename in Directory.GetFiles(strSourceFolder))
{
if (File.Exists(filename))
{
//create an object
Microsoft.Office.Interop.Excel.Workbook objBookSource = ExcelApp.Workbooks._Open
(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
//Browse through all files.
foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in objBookSource.Worksheets)
{
sheet.Copy(Type.Missing, objBookDest.Worksheets[objBookSource.Worksheets.Count]);
}
objBookSource.Close(Type.Missing, Type.Missing, Type.Missing);
objBookSource = null;
}
}
objBookDest.SaveAs(strDestinationFile, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
objBookDest.Close(Type.Missing, Type.Missing, Type.Missing);
objBookDest = null;
ExcelApp = null;
}
catch (System.Exception e)
{
//Catch
}
}
You can try ZetExcel for Excel automation using C#. ZetExcel for .NET contains APIs to be used with .NET Framework, .NET Core & Xamarin platform.

Open Excel File on a specific worksheet

I have an Excel file with 5 worksheets and I want with c# code to open it
and when it is opened I want the sheet number 3 to be activated.
How can I do that?
Like this:
using Excel;
Excel.Application excelApp = new Excel.ApplicationClass();
// if you want to make excel visible to user, set this property to true, false by default
excelApp.Visible = true;
// open an existing workbook
string workbookPath = "c:/SomeWorkBook.xls";
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
// get all sheets in workbook
Excel.Sheets excelSheets = excelWorkbook.Worksheets;
// get some sheet
string currentSheet = "Sheet1";
Excel.Worksheet excelWorksheet =
(Excel.Worksheet)excelSheets.get_Item(currentSheet);
// access cell within sheet
Excel.Range excelCell =
(Excel.Range)excelWorksheet.get_Range("A1", "A1");
Hope this helps
MDSN info here
What about something like this: (untested)
//using Excel = Microsoft.Office.Interop.Excel;
Excel.ApplicationClass app = new Excel.ApplicationClass();
Excel.Workbook workbook = app.Workbooks.Open("YourFile.xls",
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets["Number 3"];
worksheet.Activate();
If wanting to present visual feedback to the User, these two statements will set the activated sheet and select the range accordingly:
Consider including the following statement immediately prior to initializing the Excel.Range...
// Set Active sheet in Excel
excelWorksheet.Activate()
Also consider the following statement immediately after initializing the Excel.Range...
// Set Active range in Excel
excelCell.Activate()
public static Workbook openExternalWorkBook(String fileName)
{
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
return excel.Workbooks.Open(fileName, false);
}

Categories