Exporting to Excel rich text box - c#

In c#, Rich text content are saved to database in below format
< b>Hello< /b>.
I need to export this to MS Excel sheet as Hello (with bold letters)
When ever i try to export the content in excel , its not showing in rich text. Kindly help me . Thanks,
var workbook = new HSSFWorkbook();
var sheet = workbook.CreateSheet("");
int rowNumber = 1;
NPOI.SS.UserModel.IFont font = workbook.CreateFont();
font.Boldweight = (short)(NPOI.SS.UserModel.FontBoldWeight.BOLD);
font.FontHeight = 210;
font.FontName = "Calibri";
NPOI.SS.UserModel.ICellStyle headerCell = workbook.CreateCellStyle();
headerCell.FillBackgroundColor = NPOI.SS.UserModel.IndexedColors.GREY_25_PERCENT.Index;
headerCell.FillForegroundColor = NPOI.SS.UserModel.IndexedColors.GREY_25_PERCENT.Index;
headerCell.FillPattern = NPOI.SS.UserModel.FillPatternType.SOLID_FOREGROUND;
headerCell.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER;
headerCell.WrapText = true;
headerCell.SetFont(font);
headerCell.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
headerCell.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;
headerCell.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;
headerCell.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;
NPOI.SS.UserModel.IFont fontShort = workbook.CreateFont();
fontShort.Boldweight = (short)(NPOI.SS.UserModel.FontBoldWeight.NORMAL);
fontShort.FontName = "Calibri";
NPOI.SS.UserModel.ICellStyle normalCell = workbook.CreateCellStyle();
normalCell.FillBackgroundColor = 50;
normalCell.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER;
normalCell.WrapText = true;
normalCell.SetFont(fontShort);
normalCell.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
normalCell.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;
normalCell.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;
normalCell.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;
NPOI.SS.UserModel.ICellStyle emptyCell = workbook.CreateCellStyle();
emptyCell.SetFont(font);
emptyCell.BorderBottom = NPOI.SS.UserModel.BorderStyle.NONE;
emptyCell.BorderLeft = NPOI.SS.UserModel.BorderStyle.NONE;
emptyCell.BorderRight = NPOI.SS.UserModel.BorderStyle.NONE;
emptyCell.BorderTop = NPOI.SS.UserModel.BorderStyle.NONE;
var headerRow = sheet.CreateRow(0);
var output ="<b>HelloWorld</b>"
var row = sheet.CreateRow(rowNumber++);
row.CreateCell(0).SetCellValue(output);
row.Cells[0].CellStyle = normalCell;

Related

Make pdf with Graph and Data in ASP .NET Core

I've used following code for making Graphs into pdf. I want to write data into pdf file as well. Currently only graph exported in pdf. I want the excel table exported also in the pdf file.
[Route("/chart")]
public IActionResult CreateChart()
{
using (ExcelEngine excelEngine = new ExcelEngine())
{
IApplication application = excelEngine.Excel;
application.DefaultVersion = ExcelVersion.Excel2013;
IWorkbook workbook = application.Workbooks.Create(1);
IWorksheet sheet = workbook.Worksheets[0];
sheet.Range["A1"].Text = "Month";
sheet.Range["B1"].Text = "Product A";
sheet.Range["C1"].Text = "Product B";
sheet.Range["A2"].Text = "Jan";
sheet.Range["A3"].Text = "Feb";
sheet.Range["A4"].Text = "Mar";
sheet.Range["A5"].Text = "Apr";
sheet.Range["A6"].Text = "May";
Random r = new Random();
for (int i = 2; i <= 6; i++)
{
for (int j = 2; j <= 3; j++)
{
sheet.Range[i, j].Number = r.Next(0, 500);
}
}
IChartShape chart = sheet.Charts.Add();
chart.ChartType = ExcelChartType.Line;
chart.ChartTitle = "Product Sales comparison";
IChartSerie productA = chart.Series.Add("ProductA");
productA.Values = sheet.Range["B2:B6"];
productA.CategoryLabels = sheet.Range["A2:A6"];
IChartSerie productB = chart.Series.Add("ProductB");
productB.Values = sheet.Range["C2:C6"];
productB.CategoryLabels = sheet.Range["A2:A6"];
XlsIORenderer renderer = new XlsIORenderer();
Syncfusion.Pdf.PdfDocument pdfDocument = renderer.ConvertToPDF(sheet);
MemoryStream stream = new MemoryStream();
pdfDocument.Save(stream);
stream.Flush();
stream.Position = 0;
return File(stream, "application/pdf", "chart.pdf");
}
}

How to sort PivotTable (DESC values) with Interop.Excel (C#)

How to sort a PivotTable with Interop.Excel and C#?
I got the generation of the PivotTable fully like I want it to, but struggling with the sorting...
Sorting should be done, that for "Title" and "SubTitle" the fields "Value2" are always having the highest descending values at the top per project.
Was trying around via Range.Sort() but without luck.
Tested way:
Defining a region (like I did manually in Excel for figuring out the way) with "C4" and the doing a Range.Sort on this. But then it is working for the first project, but not for all. Imho, because I set this only to the pointed range to one cell. The next try was to extend the range, but then I always got HRESULT exceptions with just an memory address given (useless for me).
The screenshots are showing the wanted sorting.
public void GeneratePivot()
{
const string numberFormat = "#,##0 €;-#,##0 €";
var missing = Type.Missing;
string dataContext = #"DataContext";
#region // Create Data
var dt = new DataTable();
dt.Columns.Add(new DataColumn() { ColumnName = "Project", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Title", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "SubTitle", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value1", DataType = typeof(decimal) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value2", DataType = typeof(decimal) });
var row1 = dt.NewRow();
row1["Project"] = "Project1";
row1["Title"] = "Title1";
row1["SubTitle"] = "SubTitle1-1";
row1["Value1"] = 1000M;
row1["Value2"] = 40000M;
dt.Rows.Add(row1);
var row2 = dt.NewRow();
row2["Project"] = "Project2-1";
row2["Title"] = "Title2";
row2["SubTitle"] = "SubTitle2-1";
row2["Value1"] = 100M;
row2["Value2"] = 4000M;
dt.Rows.Add(row2);
var row3 = dt.NewRow();
row3["Project"] = "Project2-2";
row3["Title"] = "Title2";
row3["SubTitle"] = "SubTitle2-2";
row3["Value1"] = 220M;
row3["Value2"] = 222000M;
dt.Rows.Add(row3);
var row4 = dt.NewRow();
row4["Project"] = "Project3-1";
row4["Title"] = "Title3";
row4["SubTitle"] = "SubTitle3-1";
row4["Value1"] = 32423M;
row4["Value2"] = 430M;
dt.Rows.Add(row4);
var row5 = dt.NewRow();
row5["Project"] = "Project3-2";
row5["Title"] = "Title3";
row5["SubTitle"] = "SubTitle3-2";
row5["Value1"] = 2341M;
row5["Value2"] = 4002000M;
dt.Rows.Add(row5);
#endregion
// Create Workbook with Excel Interop
Excel.Application excelApplication = new Excel.Application();
Excel.Workbooks workbooks = excelApplication.Workbooks;
var workbook = workbooks.Add();
#region // Create DataSheet
Excel.Worksheet worksheet1 = workbook.Sheets[1];
worksheet1.Name = "DataSheet";
var colsCount = dt.Columns.Count;
var rowsCount = dt.Rows.Count;
Excel.Range range;
// Create DataArray from DataTable
object[,] dtArray = new object[rowsCount, colsCount];
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < colsCount; j++) { dtArray[i, j] = dt.Rows[i][j]; }
}
// Create header
range = worksheet1.Cells[1, 1];
range = range.get_Resize(1, colsCount);
range.NumberFormat = "#";
range.Font.Bold = true;
range.Value = new string[5] { "Project", "Title", "SubTitle", "Value1", "Value2" };
// Get an Excel Range of the same dimensions
range = (Excel.Range)worksheet1.Cells[2, 1];
range = range.get_Resize(rowsCount, colsCount);
// Assign the 2-d array to the Excel Range
range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, dtArray);
range = worksheet1.UsedRange;
worksheet1.Names.Add("DataContext", range);
#endregion
#region // Create PivotSheet
Excel.Worksheet worksheet2 = workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]);
worksheet2.Name = "PivotSheet";
Excel.PivotCache pivotCache;
Excel.PivotTable pivotTable;
Excel.Range pivotData;
Excel.Range pivotDestination;
// Select a range of data for the Pivot Table.
pivotData = worksheet1.get_Range(dataContext);
// Select location of the Pivot Table.
pivotDestination = worksheet2.get_Range("A1", missing);
// create Pivot Cache and Pivot Table
pivotCache = (Excel.PivotCache)workbook.PivotCaches()
.Add(Excel.XlPivotTableSourceType.xlDatabase, pivotData);
pivotTable = (Excel.PivotTable)worksheet2.PivotTables()
.Add(PivotCache: pivotCache, TableDestination: pivotDestination, TableName: dataContext);
// Style Pivot Table
pivotTable.Format(Excel.XlPivotFormatType.xlReport2);
pivotTable.InGridDropZones = false;
pivotTable.SmallGrid = false;
pivotTable.TableStyle2 = "PivotStyleLight16";
// ROW FIELDS
Excel.PivotField rowField3 = (Excel.PivotField)pivotTable.PivotFields("SubTitle");
rowField3.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField3.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField3.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField3.LayoutCompactRow = true;
Excel.PivotField rowField2 = (Excel.PivotField)pivotTable.PivotFields("Title");
rowField2.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField2.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField2.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField2.LayoutCompactRow = true;
Excel.PivotField rowField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
rowField1.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField1.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField1.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField1.LayoutCompactRow = true;
// FILTER FIELDS
Excel.PivotField pageField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
pageField1.Orientation = Excel.XlPivotFieldOrientation.xlPageField;
pageField1.EnableMultiplePageItems = true;
// DATA FIELDS
int position = 1;
Excel.PivotField dataField1 = (Excel.PivotField)pivotTable.PivotFields("Value1");
dataField1.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField1.Function = Excel.XlConsolidationFunction.xlSum;
dataField1.NumberFormat = numberFormat;
dataField1.Position = position++;
Excel.PivotField dataField2 = (Excel.PivotField)pivotTable.PivotFields("Value2");
dataField2.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField2.Function = Excel.XlConsolidationFunction.xlSum;
dataField2.NumberFormat = numberFormat;
dataField2.Position = position++;
#endregion
// Close Excel
workbook.SaveAs("Interop.Excel_Pivot.xlsx");
workbook.Close();
excelApplication.Quit();
}
This did it!
var pivotLine = (Excel.PivotLine)pivotTable.PivotColumnAxis.PivotLines[2];
rowField2.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
rowField3.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
Hint: Beware of, that given String "Summe von " is german language and will be "Sum of " with Excel in English. ;)

c# Merged cells as header address epplus

How do I set HeaderAddress to two cells of a clustered bar chart in EPPlus? I have the below data from my database output, where first column is as you can see merged cells.
I am looking for the following layout of the data
Please take note that the images are from a replica of the data, but generated inside Excel.
What I've tried so far is basically
ExcelChartSerie s = chart.Series.Add(axis.Address, xAxis.Address);
s.HeaderAddress = new ExcelAddress(startRow + r, GetColumnNumberByName(startColumn), startRow + 1, GetColumnNumberByName(startColumn) + 1);
where I more or less select the current row and two columns. This gives me "Address must be a row, column or single cell", but in order to get this to work, I must select multiple cells, no?
Epplus does not have the ability to set it. it is not so difficult but it requires XML manipulation. Kind of ugly but it gets the job done. Not knowing your code I made up a quick unit test that demos. It has to match to the right chart type so if it is not BarClustered let me know:
[TestMethod]
public void Chart_Meged_Header_Test()
{
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[]
{
new DataColumn("Col1", typeof (string)),
new DataColumn("Col2", typeof (int))
});
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow();
row[0] = $"item {(i%2 == 0 ? "A" : "B")}";
row[1] = i * 10;
datatable.Rows.Add(row);
}
//Create a test file
var fileInfo = new FileInfo(#"c:\temp\Chart_Meged_Header_Test.xlsx");
if (fileInfo.Exists)
fileInfo.Delete();
using (var pck = new ExcelPackage(fileInfo))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells["B1"].LoadFromDataTable(datatable, true);
worksheet.Column(4).Style.Numberformat.Format = "m/d/yyyy";
var chart = worksheet.Drawings.AddChart("chart test", eChartType.BarClustered);
var serie = chart.Series.Add(worksheet.Cells["C2:C11"], worksheet.Cells["B2:B11"]);
chart.SetPosition(0, 0, 3, 0);
chart.SetSize(120);
//Add merged headers
worksheet.Cells["A2"].Value = "Group 1";
worksheet.Cells["A2:A6"].Merge = true;
worksheet.Cells["A7"].Value = "Group 2";
worksheet.Cells["A7:A11"].Merge = true;
//Get reference to the worksheet xml for proper namespace
var chartXml = chart.ChartXml;
var nsm = new XmlNamespaceManager(chartXml.NameTable);
var nsuri = chartXml.DocumentElement.NamespaceURI;
nsm.AddNamespace("c", nsuri);
//Get the Series ref and its cat
var serNode = chartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser", nsm);
var catNode = serNode.SelectSingleNode("c:cat", nsm);
//Get Y axis reference to replace with multi level node
var numRefNode = catNode.SelectSingleNode("c:numRef", nsm);
var multiLvlStrRefNode = chartXml.CreateNode(XmlNodeType.Element, "c:multiLvlStrRef", nsuri);
//Set the proper cell reference and replace the node
var fNode = chartXml.CreateElement("c:f", nsuri);
fNode.InnerXml = numRefNode.SelectSingleNode("c:f", nsm).InnerXml;
fNode.InnerXml = fNode.InnerXml.Replace("$B$2", "$A$2");
multiLvlStrRefNode.AppendChild(fNode);
catNode.ReplaceChild(multiLvlStrRefNode, numRefNode);
//Set the multi level flag
var noMultiLvlLblNode = chartXml.CreateElement("c:noMultiLvlLbl", nsuri);
var att = chartXml.CreateAttribute("val");
att.Value = "0";
noMultiLvlLblNode.Attributes.Append(att);
var catAxNode = chartXml.SelectSingleNode("c:chartSpace/c:chart/c:plotArea/c:catAx", nsm);
catAxNode.AppendChild(noMultiLvlLblNode);
pck.Save();
}
}
Gives this as the output:

C# Change Excel Chart Axis Format using EPPLUS

Is there anyway to change the chart X or Y axis to set a custom label formatting?
For example, in the XAxis my labels are datetime but the formatting is yyyy-mm-dd hh:mm:ss. I would like to change it to just yyyy-mm-dd.
Was wondering if it is possible in EPPLUS without using interop
This is a bit of a pain with charts and EPPlus. They have exposed the chart.XAxis.Format property to set the format but does not account for the attribute souceLinked which, when not set to 0 (default) tells excel to just go with the source data format. So you have to set it manually with xml:
[TestMethod]
public void Chart_Row_Offset_Test()
{
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[]
{
new DataColumn("Col1", typeof (DateTime)), new DataColumn("Col2", typeof (int)), new DataColumn("Col3", typeof (object))
});
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow();
row[0] = DateTime.Now.AddDays(i) ;row[1] = i*10;row[2] = Path.GetRandomFileName();
datatable.Rows.Add(row);
}
//Create a test file
var fi = new FileInfo(#"c:\temp\Chart_Row_Offset.xlsx");
if (fi.Exists)
fi.Delete();
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
//This would be the axis label format if the XML Attribute is not set below
worksheet.Cells["A2:A11"].Style.Numberformat.Format = "m/d/yyyy";
const int EXCELCHARTWIDTH = 375;
const int EXCELCHARTHEIGHT = 350;
const double EXCELDEFAULTROWHEIGHT = 20.0; //Assuming standard screen dpi
var startCell = (ExcelRangeBase)worksheet.Cells["A1"];
for (var i = 0; i < 10; i++)
{
var chart = worksheet.Drawings.AddChart("chart " + i, eChartType.XYScatterLines);
chart.SetSize(EXCELCHARTWIDTH, EXCELCHARTHEIGHT);
chart.SetPosition(startCell.Start.Row, 0, startCell.Start.Column, 0);
chart.XAxis.Format = "yyyy-mm-dd";
var series = chart.Series.Add(worksheet.Cells["B2:B11"], worksheet.Cells["A2:A11"]);
var chartcellheight = (int)Math.Ceiling(EXCELCHARTHEIGHT / EXCELDEFAULTROWHEIGHT);
startCell = startCell.Offset(chartcellheight, 0);
//Get reference to the chart xml for proper namespace
var xdoc = chart.ChartXml;
var nsm = new XmlNamespaceManager(xdoc.NameTable);
nsm.AddNamespace("default", xdoc.DocumentElement.NamespaceURI);
//Add the attribute to not link to the source data format
var att = xdoc.CreateAttribute("sourceLinked");
att.Value = "0";
var numFmtNode = xdoc.SelectSingleNode("/default:chartSpace/default:chart/default:plotArea/default:valAx/default:numFmt", nsm);
numFmtNode.Attributes.Append(att);
}
pck.Save();
}
}

How to convert this VBA Excel code to C#

I am trying to convert excel VBA code to c#. This code must be executed outside excel and I am going to convert my excel macros to do so. Here is the code to convert
ActiveWindow.Zoom = 85
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Cells.Select
Here is what I got so far:
var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Visible = true;
excelApp.ActiveWindow.Zoom = 85;
excelApp.Range["A1"].Select();
I cannot figure out the rest below the Range("A1").Select. Any help on this
The with statement is a VB thing only, with c# you have to create a variable and call each of the properties from that variable explicitly
ActiveWindow.Zoom = 85;
Range["A1"].Select();
Range(Selection, Selection.End(xlToRight)).Select();
Selection.HorizontalAlignment = xlCenter;
Selection.VerticalAlignment = xlBottom;
Selection.WrapText = true;
Selection.Orientation = 0;
Selection.AddIndent = false;
Selection.IndentLevel = 0;
Selection.ShrinkToFit = false;
Selection.ReadingOrder = xlContext;
Selection.MergeCells = false;
Cells.Select();
(this is just a sample, do adjust your COM handling as required)
EDIT: Changed brackets to square brackets one the second line.
You need the namespace "Microsoft.Office.Interop.Excel".
using Microsoft.Office.Interop.Excel;
MyClass{
...
var app = new Application { Visible = true, ScreenUpdating = true, DisplayAlerts = false };
Workbook book = app.Workbooks.Open(path); //path is the fullFileName as string
Worksheet sheet = book.Worksheets[1];
Range range = sheet.get_Range("A1", "A1");
range.Select();
range.HorizontalAlignment = Constants.xlCenter;
range.VerticalAlignment = Constants.xlBottom;
range.WrapText = true;
range.Orientation = 0;
range.AddIndent = false;
range.IndentLevel = 0;
range.ShrinkToFit = false;
range.ReadingOrder = Constants.xlContext;
range.MergeCells = false;
}
Enjoy it!

Categories