Highlighting cells/making them bold in Excel - c#

In a group project I have to write a table to an Excel sheet. This I have done but I need to highlight the table area where the data goes, as can be seen on these pictures:
https://gyazo.com/51c57897d9a1ce8df000d6ff0f18de20
https://gyazo.com/bcc879cd7d1c5f12ccb853490dca22f2
The first picture shows how it should look without data, and the second picture shows my current file with the data loaded.
Is it possible to highlight like it is seen in the first picture where the data is supposed to be?
I have not been able to find any sources dealing with this online.
Here is the code that creates the Excel sheet. Take note that I have not looked into formatting the code properly, but it should be readable:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExcelLibrary.SpreadSheet;
using System.Data;
using System.IO;
using System.Windows;
using Excel = Microsoft.Office.Interop.Excel;
namespace ProjectXstaal
{
class Print
{
public void LoadToExcel(DataTable dt)
{
string filetest = "filetest.xlsx";
double allHours = 0;
double overtimeHours = 0;
if (File.Exists(filetest))
{
File.Delete(filetest);
}
Excel.Application oApp;
Excel.Worksheet oSheet;
Excel.Workbook oBook;
oApp = new Excel.Application();
oBook = oApp.Workbooks.Add();
Excel.Worksheet ws = (Excel.Worksheet)oApp.ActiveSheet;
// Calculates the total hours worked and total overtime hours. not important for the question
for (int i = 0; i < dt.Rows.Count; i++)
{
string overtimeTemp = dt.Rows[i][3].ToString();
string temp = dt.Rows[i][2].ToString();
double temp2 = Double.Parse(temp);
double temp3 = Double.Parse(overtimeTemp);
overtimeHours += temp3;
allHours += temp2 + temp3;
if (i >= 40)
{
break;
}
}
// some formatting of the page
ws.Cells[3, 1] = "Tidsperiode:";
ws.Cells[3, 5] = "NAVN";
ws.Cells[3, 6] = dt.Rows[1][7].ToString();
ws.Cells[1, 5] = DateTime.Now.Year.ToString();
ws.Cells[1, 3] = "ARBEJDSSEDDEL";
ws.Cells[40, 1] = "SAMMENLAGT FOR UGEN";
ws.Cells[40, 5] = allHours;
ws.Cells[41, 1] = "UGENS TIMER FORDELES PÅ";
ws.Cells[43, 5] = overtimeHours;
ws.Cells[42, 5] = allHours - overtimeHours;
ws.Cells[42, 4] = "NORMALTIMER";
ws.Cells[43, 4] = "OVERARBEJDE";
ws.Cells[6, 1] = dt.Columns[1].ToString();
ws.Cells[6, 2] = dt.Columns[5].ToString();
ws.Cells[6, 3] = dt.Columns[0].ToString();
ws.Cells[6, 4] = dt.Columns[4].ToString();
ws.Cells[6, 5] = dt.Columns[2].ToString();
ws.Cells[6, 6] = dt.Columns[3].ToString();
ws.Cells[6, 7] = dt.Columns[6].ToString();
//prints the datatable to the excel sheet and stops when it cant fit anymore information
for (int i = 0; i < dt.Rows.Count; i++)
{
ws.Cells[i + 7, 1] = dt.Rows[i][1].ToString();
ws.Cells[i + 7, 2] = dt.Rows[i][5].ToString();
ws.Cells[i + 7, 3] = dt.Rows[i][0].ToString();
ws.Cells[i + 7, 4] = dt.Rows[i][4].ToString();
ws.Cells[i + 7, 5] = dt.Rows[i][2].ToString();
ws.Cells[i + 7, 6] = dt.Rows[i][3].ToString();
ws.Cells[i + 7, 7] = dt.Rows[i][6].ToString();
ws.Cells[i + 7, 1].Bold = true;
if (i >= 32)
{
break;
}
}
// Sets column width of the data.
ws.Range["A6"].ColumnWidth = 11;
ws.Range["B6"].ColumnWidth = 10;
ws.Range["C6"].ColumnWidth = 6.7;
ws.Range["D6"].ColumnWidth = 11;
ws.Range["E6"].ColumnWidth = 11;
ws.Range["F6"].ColumnWidth = 15;
ws.Range["G6"].ColumnWidth = 15;
oBook.SaveAs(filetest);
oBook.Close();
oApp.Quit();
MessageBox.Show("Det virker måske");
}
}
}

If you now the range which should be bold, use:
Microsoft.Office.Interop.Excel.Range range = xlWorkSheet.get_Range("A1:A6","G1:G6");
range.Font.Bold = true;
In this example, the first 6 rows and the first 7 seven columns get bold, assuming the cell in the top-left corner is "A1".
I hope this helps!

Related

Data successfully export to Excel from gridview except ID column

Here is my code...
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = Excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)Excel.ActiveSheet;
Excel.Visible = true;
ws.Cells[1, 1] = "ID";
ws.Cells[1, 2] = "Name";
ws.Cells[1, 3] = "Detail";
ws.Cells[1, 4] = "Category";
ws.Cells[1, 5] = "Brand";
ws.Cells[1, 6] = "In Stock";
ws.Cells[1, 7] = "Price";
ws.Cells[1, 8] = "Total";
for (int i = 2; i <= dgDetail.Rows.Count; i++)
{
for (int j = 2; j <= 8; j++)
{
ws.Cells[i, j] = dgDetail.Rows[i - 2].Cells[j - 1].Value;
}
}
Excel has 1,1 based arrays, the first cell is 1,1, so you did it right when you put "ID" to this cell. Your gridview looks zero-based.
1) You start to export dgDetail from row 0, which I think is right, but you skip one last row - you can rewrite your code a little bit to see it:
for (int i = 0; i <= dgDetail.Rows.Count-2; i++) {
dgDetail.Rows[i]; //pseudocode
}
Maybe it's how you planned it, but you don't export row dgDetail.Row.Count - 1
2)
for (int j = 2; j <= 8; j++) {
ws.Cells[i, j] = dgDetail.Rows[i - 2].Cells[j - 1].Value;
}
Here you need to change the first value of j to 1, because you start from second column otherwise:
ws.Cells[i, 2] = dgDetail.Rows[i - 2].Cells[2 - 1].Value;
I guess you are just confused by excel 1,1 based arrays a little bit,
Also, if you have big exports, it's better to write the whole array in one operation:
Range range = worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[2, 2]];
range.Value = new object[2, 2] { { 1, 2 }, { 3, 4 } };

Excel Exception from HRESULT: 0x800A03EC

I am trying to update a program that does work for office 2010 but gives an error for 2013.
The code I am running is this:
private static bool writeToExcel(DataTable dT)
{
// Create a new Excel document
Console.Write("Opening Excel...");
Excel.Application objExcel = new Excel.Application();
objExcel.Visible = false;
Excel.Workbooks objBooks = objExcel.Workbooks;
Excel.Workbook objBook = objBooks.Add();
Excel.Worksheet objSheet = (Excel.Worksheet)objExcel.Worksheets["Sheet1"]; objSheet.Name = "Data";
Excel.Worksheet newWorksheet;
newWorksheet = (Excel.Worksheet)objExcel.Worksheets.Add();
Excel.Worksheet objSheet2 = (Excel.Worksheet)objExcel.Worksheets["Sheet2"]; objSheet2.Name = "Data2";
Excel.Range objRange;
objSheet2.Cells[2, 1] = "###";
objSheet2.Cells[3, 1] = "###";
objSheet2.Cells[4, 1] = "$$$";
objSheet2.Cells[1, 2] = "%%%";
objSheet2.Cells[2, 2] = %%%Count;
objSheet2.Cells[3, 2] = %%%RespCount;
objSheet2.Cells[4, 2] = Math.Round(%%%RespCount / %%%Count, 1);
objSheet2.Cells[1, 3] = "^^^";
objSheet2.Cells[2, 3] = ^^^Count;
objSheet2.Cells[3, 3] = ^^^RespCount;
objSheet2.Cells[4, 3] = Math.Round(^^^Count / ^^^RespCount, 1);
objSheet2.Cells[1, 5] = "&&&";
objSheet2.Cells[2, 5] = &&&;
objSheet2.Cells[3, 5] = &&&Resp;
objSheet2.Cells[4, 5] = Math.Round(&&& / &&&Resp, 1);
objSheet2.Cells[1, 6] = "***";
objSheet2.Cells[2, 6] = ***;
objSheet2.Cells[3, 6] = ***Resp;
objSheet2.Cells[4, 6] = Math.Round(*** / ***Resp, 1);
// Add the column headers
int colCount = 1;
int rowCount = 1;
foreach (DataColumn column in dT.Columns)
{
Console.Write(".");
objSheet.Cells[rowCount, colCount] = DB.GetColumnName(column.ColumnName);
if (column.DataType == System.Type.GetType("System.String"))
{
objRange = objExcel.Range[objExcel.Cells[2, colCount], objExcel.Cells[dT.Rows.Count + 1, colCount]];
objRange.NumberFormat = "#";
}
if (column.DataType == System.Type.GetType("System.DateTime"))
{
objRange = objExcel.Range[objExcel.Cells[2, colCount], objExcel.Cells[dT.Rows.Count + 1, colCount]];
objRange.NumberFormat = "m/d/yy h:mm AM/PM";
}
colCount++;
}
// Format the column headers
Console.WriteLine();
Console.Write("Adding columns...");
try
{
objSheet.Range[objExcel.Cells[rowCount + 1, 1], objExcel.Cells[rowCount + 1, dT.Columns.Count]].Select();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
The Error I get when I try it on a Win 7 PC running Office 2013 is this.
System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC
at System.Dynamic.ComRuntimeHelpers.CheckThrowException(Int32 hresult,
ExcepInfo& excepInfo, UInt32 argErr, String message)
at CallSite.Target(Closure , CallSite , Object , Object , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at CscSurveyReporter.Program.writeToExcel(DataTable dT) in c:\tfs_csc\csc\CscSurveyReporter\CscSurveyReporter\Program.cs:line 236
The line I am having the exception on is:
objSheet.Range[objExcel.Cells[rowCount + 1, 1], objExcel.Cells[rowCount + 1, dT.Columns.Count]].Select();
I have looked online for a solution and I have tried to update the Microsoft.Office.Interop.Excel and I have also tried to remove a registry folder but nothing I have found and tried has worked.
I found two ways to solve the issue:
1)
int column = 0, row = 0;
foreach (DataColumn col in dT.Columns)
{
objExcel.Cells[1, ++column] = col.ColumnName;
}
foreach (DataRow r in dT.Rows)
{
row++;
column = 0;
foreach (DataColumn c in dT.Columns)
{
objExcel.Cells[row + 1, ++column] = r[c.ColumnName];
}
}
This worked but increased the run time of the application.
After I had that working I looked more at the line that was in error and changed it from:
objSheet.Range[objExcel.Cells[rowCount + 1, 1], objExcel.Cells[rowCount + 1, dT.Columns.Count]].Select();
too this:
objSheet.Range[objSheet.Cells[rowCount + 1, 1], objSheet.Cells[rowCount + 1, dT.Columns.Count]].Select();
I am posting this just incase anyone else has the same issue.

I'm getting error when using Microsoft.Office.Interop.Excel; namespace with controls new point syntax in C#

i'm trying to change location of controls using
label1.Location = new Point(x,y);
but i also want to export data from data grid view to excel, for doing this i'm using
using Microsoft.Office.Interop.Excel;
but when i use this, namespace compiler shows error in
label1.Location = new Point(x,y);
Error : 'Point' is an ambiguous reference between 'System.Drawing.Point' and 'Microsoft.Office.Interop.Excel.Point'
Code for exporting data to excel :
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = Excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)Excel.ActiveSheet;
Excel.Visible = true;
ws.Cells[1, 1] = "ID";
ws.Cells[1, 2] = "Products Name";
ws.Cells[1, 3] = "Products Id";
ws.Cells[1, 4] = "Products Price";
ws.Cells[1, 5] = "Selling Price";
for (int j = 2; j <= dataGridView1.Rows.Count; j++)
{
for (int i = 2; i <= 5; i++)
{
ws.Cells[j, i] = dataGridView1.Rows[j - 2].Cells[i - 1].Value;
}
}
Code for new points :
linkLabel7.Show();
linkLabel7.Location = new Point(293, 59);
You can use aliases for your namespaces
using Excel = Microsoft.Office.Interop.Excel;
using Drawing = System.Drawing;
and use it like this
label1.Location = new Drawing.Point(x,y);
look at the MSDN reference here

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.

Excel.Range Copy() works very slowly

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.

Categories

Resources