Excel.Range Copy() works very slowly - c#

I'm building a report in which try to copy the previous row cell styles in the following
for (int i = 0; i < DataSource.Length; i++)
{
int rowNumber = i + s;
Excel.Range RngToCopy = ObjWorkSheet.get_Range("A" + rowNumber.ToString(), "K" + rowNumber.ToString());
Excel.Range r = ObjWorkSheet.get_Range("A" + (rowNumber + 1).ToString(), "K" + (rowNumber + 1).ToString());
RngToCopy.Copy(Type.Missing);
r.Insert(Excel.XlInsertShiftDirection.xlShiftDown);
r.PasteSpecial(Excel.XlPasteType.xlPasteFormats,
Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
ObjWorkSheet.Cells[rowNumber, 1] = i + 1;
ObjWorkSheet.Cells[rowNumber, 2] = DataSource[i].TerminalName;
ObjWorkSheet.Cells[rowNumber, 3] = DataSource[i].Type;
ObjWorkSheet.Cells[rowNumber, 4] = DataSource[i].Requisite;
}
everything works but very long
How can I speed this up?

I think you manually copy you will be improved.
Object[] origData = origRange.Value2;
destRange.Value2 = origData;
That should be WAY faster.

Related

Formula not identify cell values

I'm generating an excel using the following code in my ASP.Net MVC Application
var fileName = DateTime.Now.ToString("yyyy-MM-dd--hh-mm-ss") + ".xlsx";
var outputDir = ConfigurationManager.AppSettings["ExcelUploadPath"];
// var fileName = "ExcellData.xlsx";
var file = new FileInfo(outputDir + fileName);
var fDate = JsonConvert.DeserializeObject<DateTime>(fromDate);
var tDate = JsonConvert.DeserializeObject<DateTime>(toDate);
using (var package = new OfficeOpenXml.ExcelPackage(file))
{
// add a new worksheet to the empty workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Plan " + DateTime.Now.ToShortDateString());
// --------- Data and styling goes here -------------- //
DataTable dt = planService.GetFlow(fDate, tDate, customerId, ordertypeId, suppliers, items);
if (dt != null)
{
int iCol = 1;
// Add column headings...
for (int i = 9; i < dt.Columns.Count; i++)
{
dt.Columns[i].ColumnName = dt.Columns[i].ColumnName.MultiInsert("/", 1, 3);
}
foreach (DataColumn c in dt.Columns)
{
worksheet.Cells[1, iCol].Value = c.ColumnName;
worksheet.Cells[1, iCol].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[1, iCol].Style.Font.Bold = true;
worksheet.Cells[1, iCol].Style.Fill.BackgroundColor.SetColor(Color.LightGray);
iCol++;
}
for (int j = 0; j < dt.Rows.Count; j++)
{
for (int k = 0; k < dt.Columns.Count; k++)
{
worksheet.Cells[j + 2, k + 1].Value = dt.Rows[j].ItemArray[k].ToString();
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 6)
{
worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Cyan);
}
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 7)
{
worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Magenta);
//worksheet.Cells[j + 2, k + 1].Formula =
if((k+1) > 10){
var addressList = new List<string>();
for (int i = 11; i <= k+1; i++)
{
addressList.Add(worksheet.Cells[((j + 2) -1) , i].Address);
}
var lstAdress = String.Join(",", addressList);
worksheet.Cells[j + 2, k + 1].Formula = "SUM(" + lstAdress + ")";
}
}
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 8)
{
//worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Gray);
}
}
var colCount = dt.Columns.Count;
// worksheet.Cells[j+2, 8, j+2, colCount- 1].Style.Numberformat.Format = "0.000";
var range = worksheet.Cells[j + 2, 9, j + 2, colCount - 1];
var r = range.ToString();
var decimalValidation = worksheet.DataValidations.AddDecimalValidation(range.ToString());
decimalValidation.ShowErrorMessage = true;
decimalValidation.ErrorStyle = ExcelDataValidationWarningStyle.stop;
decimalValidation.ErrorTitle = "The value you entered is not valid";
decimalValidation.Error = "This cell must be a valid positive number.";
decimalValidation.Operator = ExcelDataValidationOperator.greaterThanOrEqual;
decimalValidation.Formula.Value = 0D;
}
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
worksheet.Column(1).Hidden = true;
worksheet.Column(2).Hidden = true;
worksheet.Column(3).Hidden = true;
worksheet.Column(4).Hidden = true;
worksheet.Column(5).Hidden = true;
worksheet.Column(8).Hidden = true;
worksheet.Column(9).Hidden = true;
worksheet.Column(10).Hidden = true;
worksheet.Protection.IsProtected = true;
// save our new workbook and we are done!
worksheet.Calculate();
package.Save();
return Json(fileName, JsonRequestBehavior.AllowGet);
}
else
{
return Json("NoData", JsonRequestBehavior.AllowGet);
}
}
return Json("", JsonRequestBehavior.AllowGet);
Here I'm setting my formula with comma separated cell names eg:
SUM(A1,A2,A3.. etc)
The excel file is generating correctly. But the problem is the formula calculation is not happen when I open my excel file.
The formula works when I manually change a cell value in Column Type Agreed Flow.
And it can only identify values of manually edited cells.
How can I resolve this?
Formula recalculation is both an Excel and a workbook setting.
You could set it with at the workbook level with
workbook.CalcMode = ExcelCalcMode.Automatic;
If the user has set it to manual though, the formulas won't be recalculated.
If you want to ensure the saved values are correct you can force the calculation by calling
worksheet.Calculate();
You can also calculate the formulas at the workbook or range level, eg :
worksheet.Cells[j + 2, k + 1].Calculate();
or
package.Workbook.Calculate();
This is explained in the documentation. Keep in mind that EPPlus doesn't contain Excel's formula engine. It uses its own engine to parse and calculate formulas. Some things aren't supported
It worked when I change my formula as follows..
var addressList = new List<string>();
for (int i = 11; i <= k+1; i++)
{
addressList.Add(worksheet.Cells[((j + 2) -1) , i].Address);
}
var lstAdress = String.Join("+", addressList);
worksheet.Cells[j + 2, k + 1].Formula = "(" + lstAdress + ")";
I think there is an issue in my excel sheet when I use the SUM function So I write the formula without using it. Then it worked
(A1+B1+C1+D1+ ..... etc)

workbook.Worksheets.Clear(); ruining size of the cell in excel

i = (i + 1) % 100;
{
worksheet.Cells.ColumnWidth[0, 1] = 10000;
workbook.Worksheets.Add(worksheet);
string myFileName = String.Format("{0}__{1}", DateTime.Now.ToString("yyyyMMdd"), ".csv");
string myFullPath = Path.Combine("C:\\", myFileName);
workbook.Save(myFileName);
worksheet.Cells[i, 0] = new Cell(DateTime.Now, #"yyyy-MM-dd--HH-mm-ss");
worksheet.Cells[i, 1] = new Cell(DataFromCOM);
worksheet.Cells[i, 2] = new Cell(val);
//workbook.Worksheets.Clear();
}
When I run workbook.Worksheets.Clear(); it removes all the formatting of the cells. It eliminates my cells column width and implements an incorrect formula, putting numbers that does not make sense instead of the date.
workbook.Worksheets.Clear();
workbook.Worksheets.Add(worksheet);
n++;
{
worksheet.Cells.ColumnWidth[0, 1] = 10000;
string myFileName = String.Format("{0}__{1}", DateTime.Now.ToString("yyyyMMdd"), ".csv");
string myFullPath = Path.Combine("C:\\", myFileName);
workbook.Save(myFileName);
worksheet.Cells[n, 0] = new Cell(DateTime.Now.ToString( #"HH:mm:ss"));
worksheet.Cells[n, 1] = new Cell(DataFromCOM);
worksheet.Cells[n, 2] = new Cell(val);
}

Reason to not multithread when writing to multiple excel worksheets

I am working on some code that a developer I replaced wrote. He wrote a lengthy piece of code what writes to multiple excel worksheets on the same excel file. I am thinking about using several background workers to speed up the process of writing to four excel worksheets. Would there be a reason why it would be a good idea to leave all this on one thread? I have used multi-threading before, but not in c# and not writing to excel. I could not find any documentation either way.
Here is the code
xlWorkSheet = xlWorkBook.Worksheets.get_Item(1);
// work order
xlWorkSheet.Cells[4, 4] = nld.s_WorkOrderNumber;
// technician
xlWorkSheet.Cells[6, 4] = nld.s_TechnicianName;
// date and time
xlWorkSheet.Cells[4, 10] = (string)DateTime.Now.ToShortDateString();
xlWorkSheet.Cells[6, 10] = (string)DateTime.Now.ToShortTimeString();
row = 30;
col = 1;
// left connectors and part number
conCount = nld.n_LeftConnCount;
for (i = 0; i < conCount; i++)
{
xlWorkSheet.Cells[row, col] = "Name: " + nld.ConnDataLeft[i].s_ConnName + " PartNo: " + nld.ConnDataLeft[i].s_ConnPartNumber;
row++;
}
// Right connectors and part number
row = 30;
col = 7;
conCount = nld.n_RightConnCount;
for (i = 0; i < conCount; i++)
{
xlWorkSheet.Cells[row, col] = "Name: " + nld.ConnDataRight[i].s_ConnName + " PartNo: " + nld.ConnDataRight[i].s_ConnPartNumber;
row++;
}
// put down the pin map onNetlist worksheet
xlWorkSheet = xlWorkBook.Worksheets.get_Item(2);
row = 5;
col = 1;
i = 0;
leftPinNum = 0;
int connCount = nld.pinMap.Count;
for(i = 0; i < connCount; i++)
{
xlWorkSheet.Cells[row, col] = (i+1).ToString();
leftPinNum = nld.pinMap[i].pinLeft;
xlWorkSheet.Cells[row, col + 1] = nld.pinMap[i].conLeftName;
xlWorkSheet.Cells[row, col + 2] = nld.pinMap[i].pinLeftName;
xlWorkSheet.Cells[row, col + 4] = nld.pinMap[i].conRightName;
xlWorkSheet.Cells[row, col + 5] = nld.pinMap[i].pinRightName;
row++;
}
// put down the pin map onNetlist worksheet
xlWorkSheet = xlWorkBook.Worksheets.get_Item(3);
row = 5;
col = 1;
i = 0;
leftPinNum = 0;
for (i = 0; i < connCount; i++)
{
xlWorkSheet.Cells[row, col] = (i + 1).ToString();
leftPinNum = nld.pinMap[i].pinLeft;
xlWorkSheet.Cells[row, col + 1] = nld.pinMap[i].conLeftName;
xlWorkSheet.Cells[row, col + 2] = nld.pinMap[i].pinLeftName;
xlWorkSheet.Cells[row, col + 4] = nld.pinMap[i].conRightName;
xlWorkSheet.Cells[row, col + 5] = nld.pinMap[i].pinRightName;
if (facadeIntoNetList.ReturnIfUseShort(i))
{
xlWorkSheet.Cells[row, col + 7] = "True";
}
else
{
xlWorkSheet.Cells[row, col + 9] = "True";
}
row++;
}
// put down the pin map onNetlist worksheet
xlWorkSheet = xlWorkBook.Worksheets.get_Item(4);
row = 5;
col = 1;
i = 0;
leftPinNum = 0;
for (i = 0; i < connCount; i++)
{
xlWorkSheet.Cells[row, col] = (i + 1).ToString();
leftPinNum = nld.pinMap[i].pinLeft;
xlWorkSheet.Cells[row, col + 1] = nld.pinMap[i].conLeftName;
xlWorkSheet.Cells[row, col + 2] = nld.pinMap[i].pinLeftName;
xlWorkSheet.Cells[row, col + 6] = nld.pinMap[i].conRightName;
xlWorkSheet.Cells[row, col + 7] = nld.pinMap[i].pinRightName;
row++;
}
I know the temptation to do this: Those Office COM interfaces are painfully slow. But they also don't support multithreading at all. It's not a C# issue, it is an Excel+COM issue. If you need speed, then write an .xlsx using a 3rd-party library then launch Excel to open the file. That might literally be hundreds of times faster.

WrapText for column in Excel programmatically

I'm trying to set WrapText property to true with C#.
Range rng = sheet.get_Range("A:A", System.Type.Missing);
rng.EntireColumn.ColumnWidth = 50;
rng.EntireColumn.AutoFit();
rng.EntireRow.AutoFit();
rng.WrapText = true;
but it doesn't work without any exceptions. What's wrong? Thank you!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.IO;
//Initial Declarations//
Excel.Workbook destinationXlWorkBook;
Excel.Worksheet destinationXlWorkSheet;
Excel.Application destinationXlApp;
object misValue = System.Reflection.Missing.Value;
//Launch Excel App//
destinationXlApp = new Excel.Application();
//Load WorkBook in the opened Excel App//
destinationXlWorkBook = destinationXlApp.Workbooks.Add(misValue);
//Load worksheet-1 in the workbook//
destinationXlWorkSheet =
(Excel.Worksheet)destinationXlWorkBook.Worksheets.get_Item(1);
//Set Text-Wrap for all rows true//
destinationXlWorkSheet.Rows.WrapText = true;
//Or, set it for specific rows//
destinationXlWorkSheet.Rows[3].WrapText = true;
destinationXlWorkSheet.Rows[5].WrapText = true;
//Edit individual cells//
xlWorkSheet.Cells[1, 1] = "ID";
xlWorkSheet.Cells[1, 2] = "Name";
xlWorkSheet.Cells[2, 1] = "1";
xlWorkSheet.Cells[2, 2] = "One";
xlWorkSheet.Cells[3, 1] = "2";
xlWorkSheet.Cells[3, 2] = "Two";
//Save and close the Excel//
destinationXlWorkBook.SaveAs("C:\\Users\\UtkarshSinha\\Documents\\SAP\\text.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
//Start quitting and closing Excel//
destinationXlWorkBook.Close(true, misValue, misValue);
destinationXlApp.Quit();
Marshal.ReleaseComObject(destinationXlWorkSheet);
Marshal.ReleaseComObject(destinationXlWorkBook);
Marshal.ReleaseComObject(destinationXlApp);
I am duping A LOT of code here, for my entire solution, TextWrap being one of it. I figure it might come in handy to someone someday.
MAIN PROGRAM:
public int counter;
public void ExportPartsToExcelButton(object sender, RoutedEventArgs e)
{
Type officeType = Type.GetTypeFromProgID("Excel.Application");
if (officeType != null)
{
if (CurrentID != 0)
{
counter = 1;
GeneratePartsXLSX();
}
else
{
MessageBoxEx.Show(this, "No address selected!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
else
{
MessageBoxEx.Show(this, "Install Microsoft Excel!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
public void GeneratePartsXLSX()
{
Mouse.OverrideCursor = Cursors.Wait;
string filename = GlobalStrings.building_house_address;
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\";
filename = filename.Replace("/", "+");
if (!File.Exists(path + filename + ".xlsx"))
{
DataGridParts.ExportPartsToExcel(path + filename + ".xlsx"); //You have to include the ".xlsx" extension, otherwise the Office interop detects a possible dot (.) in the file name as an extension. Example: road.block instead of road.block.xlsx
MessageBoxEx.Show(this, "Saved to Desktop");
}
else
{
if (!File.Exists(path + "\\" + filename + " (" + (counter) + ")" + ".xlsx"))
{
DataGridParts.ExportPartsToExcel(path + filename + " (" + (counter) + ")" + ".xlsx");
MessageBoxEx.Show(this, "Saved to Desktop");
}
else
{
counter++;
GeneratePartsXLSX();
}
}
Mouse.OverrideCursor = null;
}
CLASS:
using Microsoft.Office.Interop.Excel;
using System;
using System.Runtime.InteropServices;
namespace SAVETOEXCELPROGRAM
{
public static class ExportToExcel
{
public static void ExportPartsToExcel(this System.Data.DataTable DataTable, string ExcelFilePath = null)
{
int ColumnsCount;
int RowShift = 7;
ColumnsCount = DataTable.Columns.Count;
// load excel, and create a new workbook
Application Excel = new Application();
Excel.Workbooks.Add();
// single worksheet
_Worksheet Worksheet = Excel.ActiveSheet;
Excel.Sheets[1].Name = "WHATEVER";
Worksheet.Columns.NumberFormat = "#"; //Force the "Text" format, so that 1/2 won't get converted to 1st of February for example
Worksheet.Columns.HorizontalAlignment = XlHAlign.xlHAlignLeft; //Text aligment
Worksheet.Columns.VerticalAlignment = XlHAlign.xlHAlignCenter; //Text aligment
object[,] Title = new object[5, 1]; //Array range starts at [1,1], the content index starts at [0,0]
if (GlobalStrings.building_alterantive_addresses.Length == 0)
{
if (GlobalStrings.building_postcode.Length != 0)
{
Title[0, 0] = "DATE: " + DateTime.Now.ToString("dd.MM.yyyy - HH:mm");
Title[2, 0] = "ADDRESS: " + GlobalStrings.building_house_street + " " + GlobalStrings.building_house_number + GlobalStrings.building_house_id + ", " + GlobalStrings.building_postcode + " " + GlobalStrings.building_area;
Title[3, 0] = "C.C.: " + GlobalStrings.building_cadastral_community + ", BUILDING NO.: " + GlobalStrings.building_building_number + ", PLOT NO.: " + GlobalStrings.building_plot_number;
}
else
{
Title[0, 0] = "DATE: " + DateTime.Now.ToString("dd.MM.yyyy - HH:mm");
Title[2, 0] = "ADDRESS: " + GlobalStrings.building_house_street + " " + GlobalStrings.building_house_number + GlobalStrings.building_house_id;
Title[3, 0] = "C.C.: " + GlobalStrings.building_cadastral_community + ", BUILDING NO.: " + GlobalStrings.building_building_number + ", " + GlobalStrings.building_plot_number;
}
}
else
{
if (GlobalStrings.building_postcode.Length != 0)
{
Title[0, 0] = "DATE: " + DateTime.Now.ToString("dd.MM.yyyy - HH:mm");
Title[2, 0] = "ADDRESS: " + GlobalStrings.building_house_street + " " + GlobalStrings.building_house_number + GlobalStrings.building_house_id + ", " + GlobalStrings.building_postcode + " " + GlobalStrings.building_area;
Title[3, 0] = "C.C.: " + GlobalStrings.building_cadastral_community + ", BUILDING NO.: " + GlobalStrings.building_building_number + ", PLOT NO.: " + GlobalStrings.building_plot_number;
Title[4, 0] = "LOOK ALSO: " + GlobalStrings.building_alterantive_addresses;
}
else
{
Title[0, 0] = "DATE: " + DateTime.Now.ToString("dd.MM.yyyy - HH:mm");
Title[2, 0] = "ADDRESS: " + GlobalStrings.building_house_street + " " + GlobalStrings.building_house_number + GlobalStrings.building_house_id;
Title[3, 0] = "C.C.: " + GlobalStrings.building_cadastral_community + ", BUILDING NO.: " + GlobalStrings.building_building_number + ", PLOT NO.: " + GlobalStrings.building_plot_number;
Title[4, 0] = "LOOK ALSO: " + GlobalStrings.building_alterantive_addresses;
}
}
Range TitleRange = Worksheet.get_Range((Range)(Worksheet.Cells[5, 1]), (Range)(Worksheet.Cells[1, 1]));
TitleRange.Value = Title;
TitleRange.Font.Bold = true;
TitleRange.Font.Size = 10;
object[] Header = new object[14]; //Number of Headers
Header[0] = "PART";
Header[1] = "SHARE";
Header[2] = "CRP";
Header[3] = "+/-";
Header[4] = "OWNER";
Header[5] = "ADDRESS";
Header[6] = "POSTCODE";
Header[7] = "AREA";
Header[8] = "COUNTRY";
Header[9] = "SOCIAL";
Header[10] = "TYPE";
Header[11] = "DESCRIPTION";
Header[12] = "COMMENT";
Header[13] = "CODE";
int MaxCol = Header.Length;
Range HeaderRange = Worksheet.get_Range((Range)(Worksheet.Cells[RowShift, 2]), (Range)(Worksheet.Cells[RowShift, MaxCol + 1])); //MaxCol+1, because we have to shift the Array position by 1, as the first column is set to "ColumnWidth = 0.1"
HeaderRange.Value = Header;
HeaderRange.Font.Bold = true;
HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
HeaderRange.Borders.LineStyle = XlLineStyle.xlContinuous;
// DataCells
int RowsCount = DataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount]; //Array range starts at [1,1], the content index starts at [0,0]
for (int j = 0; j < RowsCount; j++)
{
for (int i = 3; i <= ColumnsCount - 2; i++) //With this you control the data range, starts with 0, you can exclude data with an " if (i != 0 && i != 1 && ... && i= 5)
{
Cells[j, i - 3] = DataTable.Rows[j][i]; //with i you control the horizontal placement of the data in the worksheet
}
}
Range CellRange = Worksheet.get_Range((Range)(Worksheet.Cells[RowShift + 1, 2]), (Range)(Worksheet.Cells[RowShift + RowsCount, MaxCol + 1])); //MaxCol+1, because we have to shift the Array position by 1, as the first column is set to "ColumnWidth = 0.1"
CellRange.Value = Cells;
CellRange.Borders.LineStyle = XlLineStyle.xlContinuous;
Worksheet.Columns[1].ColumnWidth = 0.1; //If this was set on AutoFit the Column 1 would get extended to the Title Width, because they share the column.
Worksheet.Columns[2].ColumnWidth = 3;
Worksheet.Columns[3].ColumnWidth = 4;
Worksheet.Columns[4].ColumnWidth = 3;
Worksheet.Columns[5].ColumnWidth = 2;
Worksheet.Columns[6].ColumnWidth = 13;
Worksheet.Columns[7].ColumnWidth = 15;
Worksheet.Columns[8].ColumnWidth = 4;
Worksheet.Columns[9].ColumnWidth = 8;
Worksheet.Columns[10].ColumnWidth = 6;
Worksheet.Columns[11].ColumnWidth = 10;
Worksheet.Columns[12].ColumnWidth = 18;
Worksheet.Columns[13].ColumnWidth = 16;
Worksheet.Columns[14].ColumnWidth = 18;
Worksheet.Columns[MaxCol + 1].ColumnWidth = 15; //Set the Width of the last Column
for (int b = 2; b <= MaxCol; b++) //If we wanted to include the "Header[14]", we would have to set MaxCol+1, because the Array (not the DataTable) is shifted by +1. These are Excel Worksheet settings!
{
Worksheet.Columns[b].WrapText = true;
//Worksheet.Columns[b].AutoFit();
}
for (int b = 2; b <= MaxCol + 1; b++)
{
Worksheet.Columns[b].Font.Size = 7;
}
Worksheet.PageSetup.Orientation = XlPageOrientation.xlLandscape;
Worksheet.PageSetup.TopMargin = 0.5;
Worksheet.PageSetup.BottomMargin = 0.5;
Worksheet.PageSetup.RightMargin = 0.5;
Worksheet.PageSetup.LeftMargin = 0.5;
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
Worksheet.SaveAs(ExcelFilePath);
Excel.Quit();
Marshal.FinalReleaseComObject(Worksheet);
Marshal.FinalReleaseComObject(TitleRange);
Marshal.FinalReleaseComObject(HeaderRange);
Marshal.FinalReleaseComObject(CellRange);
Marshal.FinalReleaseComObject(Excel);
}
else
// no filepath is given
{
Excel.Visible = true;
}
}
}
}
workSheet.Cells["A1:T1"].Style.WrapText = true;

Read data from Excel files

I'm having some trouble reading from an Excel spreadsheet in C#.
I have this code which I read every cell from A to X.
System.Array myvalues; string[] strArray;
Microsoft.Office.Interop.Excel.Range range =
worksheet.get_Range("A" + i.ToString(), "W" + i.ToString());
while(range.Count!=0)
{
i++;
//Console.WriteLine(i);
range = worksheet.get_Range("A" + i.ToString(), "W" + i.ToString());
myvalues = (System.Array)range.Cells.Value;
strArray = ConvertToStringArray(myvalues);
name = clearstr(strArray[1]);
for ( int j = 1 ; j <= Int32.Parse(number_add_file)*4 ; j++)
{
name = "";
lang_add = "";
price = "";
description = "";
Console.WriteLine("I got in!");
Microsoft.Office.Interop.Excel.Range range_add =
worksheet.get_Range("X" + i.ToString(),Type.Missing);
System.Array values = (System.Array)range_add.Cells.Value;
string[] str = ConvertToStringArray(values);
name = str[0];
lang_add = str[1];
price = str[2];
description = str[3];
Console.WriteLine(name + " "
+ lang_add + " " + price + " " + description);
addfile();
}
My question is: How could i read next 4 * "number" rows in excel based on "number" value ?
For example:
A B C D E F G H I J
a a a a a 1 a a a a
F's cell value is 1 so I would like to read ( G H I J)
If F's cell value is 2 the I would like to read ( G H I J K L M N)
A B C D E F G H I J K L M N
a a a a a 2 a a a a a a a a
F's cell value 3 :
A B C D E F G H I J K L M N O P Q R
a a a a a 3 a a a a a a a a a a a a
This is for .NET 4.0:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open("somefile.xls");
Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1]; // assume it is the first sheet
Excel.Range xlRange = xlWorksheet.UsedRange; // get the entire used range
int value = 0;
if(Int32.TryParse(xlRange.Cells[1,6].Value2.ToString(), out value)) // get the F cell from the first row
{
int numberOfColumnsToRead = value * 4;
for(int col=7; col < (numberOfColumnsToRead + 7); col++)
{
Console.WriteLine(xlRange.Cells[1,col].Value2.ToString()); // do whatever with value
}
}
This will open the workbook and get the first worksheet in the workbook. We then get the entire used range and put that in the range variable. From there, we try to parse the int in column "F" (which is the 6th column, it is 1 based not zero based) in the first row. If that parsing is successful, we then multiply that number by 4 to see how many columns you need (in your post you said rows, but your examples were columns). We use a for loop to start at the G column (column 7) and go to the number of columns to read + 7 (to account for the columns that we skipped). You would be free to do what you want with the values but for this example I just wrote them to the console.
It is inot direct answer to your question, but you can easily refer to your cells like this:
int row1 = 1;
int row2 = 5;
sheet1.Cells[row1, row1+row2].Value=row1.ToString();
String Rng = Convert.ToString(sheet1.Cells[row1, row2-row1].Address());
string testList = "";
String str1 = "";
string logPath = #"E:\LogForConsoleApp.txt";
string filePath = #"E:\SaveSheetName.txt";
string Path = #"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\MSTest";
List<string> ltSheetName = new List<string>();
List<string> ltMethodName = new List<string>();
Process myProcess = new Process();
Excel.Application appExl = new Excel.Application();
Excel.Workbook workbook = null;
Excel.Worksheet NwSheet;
Excel.Range ShtRange;
appExl = new Excel.Application();
workbook = appExl.Workbooks.Open("E:\\inputSheet3", Missing.Value, ReadOnly: false);
NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1);
ShtRange = NwSheet.UsedRange; //gives the used cells in sheet
int rCnt = 0;
int cCnt = 0;
for (rCnt = 1; rCnt <= ShtRange.Rows.Count; rCnt++)
{
for (cCnt = 1; cCnt <= ShtRange.Columns.Count; cCnt++)
{
if (Convert.ToString(NwSheet.Cells[rCnt, cCnt].Value2) == "Y")
{
ltSheetName.Add(NwSheet.Cells[rCnt, cCnt - 1].Value2);
//ltMethodName.Add(" /test:" + NwSheet.Cells[rCnt, cCnt - 1].Value2);
}
}
}
workbook.Close(false, Missing.Value, Missing.Value);
appExl.Quit();
for (int sht = 0; sht < ltSheetName.Count; sht++)
{
ltMethodName.Clear();
appExl = new Excel.Application();
workbook = appExl.Workbooks.Open(ltSheetName[sht].ToString(), Missing.Value, ReadOnly: false);
NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1);
ShtRange = NwSheet.UsedRange; //gives the used cells in sheet
int rCnt1 = 0;
int cCnt1 = 0;
for (rCnt1 = 1; rCnt1 <= ShtRange.Rows.Count; rCnt1++)
{
for (cCnt1 = 1; cCnt1 <= ShtRange.Columns.Count; cCnt1++)
{
if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "Y")
{
ltMethodName.Add(" /test:" + NwSheet.Cells[rCnt, cCnt - 1].Value2);
}
}
}
workbook.Close(false, Missing.Value, Missing.Value);
appExl.Quit();
for (int i = 0; i < ltMethodName.Count; i++)
{
str1 = ltMethodName[i].ToString();
testList += str1;
}
string foldername = "TestResult_" + DateTime.Today.ToString().Remove(DateTime.Today.ToString().LastIndexOf("/") + 5);
foldername = foldername.Replace("/", "");
string direc = #"E:\" + foldername;
string fileName = ltSheetName[sht].ToString().Substring(ltSheetName[sht].ToString().LastIndexOf("\\") + 1) + "_InderdeepAutRes.trx";
if (!Directory.Exists(direc))
Directory.CreateDirectory(direc);
string testcase = "";
if (!File.Exists(direc + "\\" + fileName))
testcase = " /testcontainer:" + "E:\\Practice\\TestingSample\\TestingSample\\bin\\Debug\\TestingSample.dll" + testList + " /resultsfile:" + direc + "\\" + fileName;
else
{
Directory.Delete(direc, true);
Directory.CreateDirectory(direc);
testcase = " /testcontainer:" + "E:\\Practice\\TestingSample\\TestingSample\\bin\\Debug\\TestingSample.dll" + testList + " /resultsfile:" + direc + "\\" + fileName;
}
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(Path, testcase);
try
{
TextWriter tw = new StreamWriter(filePath, false);
tw.WriteLine(ltSheetName[sht].ToString());
tw.Close();
myProcess.StartInfo = myProcessStartInfo;
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcess.Start();
string output = myProcess.StandardOutput.ReadToEnd();
//myProcess.WaitForExit();
Console.WriteLine(output);
}
catch (Exception ex)
{
TextWriter tw = new StreamWriter(logPath, true);
tw.WriteLine(ex.StackTrace);
tw.Close();
}
}

Categories

Resources