NPOI create cell containing bold and non bold text - c#

I'm using NPOI to output excel from Asp.Net MVC app and works very well with plain text but have now been requested to add formatting and am having problems where I need to have a single cell with bold text followed by non-bold text. e.g.
This text bold - this text normal
I know I can give a cell a single style but this won't help and I cannot see anyway to give a cell some pre-formatted rich text.
The only possible solution that I can think of is creating two cells separately and the merge them together but will that then mean the formatting will be lost?
Is there a way to do this that I have missed in NPOI?

You may try this:
var font = reportWorkbook.CreateFont();
font.FontHeightInPoints = 11;
font.FontName = "Calibri";
font.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.BOLD;
var cell = headerRow.CreateCell(0);
cell.SetCellValue("Test Bold");
cell.CellStyle = reportWorkbook.CreateCellStyle();
cell.CellStyle.SetFont(font);

Fortunately, you able to do that... Look at this code:
Font f1=wb.CreateFont();
f1.Color=HSSFColor.RED.index;
ws.GetRow(1).GetCell(0).RichStringCellValue.ApplyFont(1, 5, f1);

Seems that the Ernie Banzon answer no longer works exactly as described, possibly due to a namespace change (or in fact that I'm using the HSSF namespace?)
// usings
using NPOI.HSSF.UserModel;
// IWorkbook doc
IFont font = doc.CreateFont();
font.FontHeightInPoints = 11;
font.FontName = "Arial";
font.Boldweight = (short)FontBoldWeight.BOLD;

Use this option
font.Boldweight = (short)700;//FontBoldWeight.Bold;
Actual syntax should be like below. But both of these syntax doesn't works sometime
font.Boldweight = FontBoldWeight.Bold ;
Or
font.Boldweight = (short)FontBoldWeight.Bold;
FontBoldWeight is type enum, which after type casting may not work sometime. As a workaround if you type caste or use actual short value of enum directly, it works. Below is the declaration of FontBoldWeight. it will make things clear.
**public enum FontBoldWeight
{
None = 0,
Normal = 400,
Bold = 700,
}**

After a fair amount of investigation it seems that you are not able to do this inside of NPOI as it doesn't provide the necessary functionality to allow you to set formatting on specific text within a cell like I was attempting to do.

Related

Set Text Length of Cell using ClosedXML

I was wondering how do you set the text length of a cell in an Excel worksheet using ClosedXML. I have the suspicion that XLTextLengthCriteria may be helpful. I read the docs of ClosedXML but I did not find a concrete answer. Any help will be appreaciated.
For validation you can set the text length like this:
worksheet.Cell(1,1).SetDataValidation().TextLength.EqualOrLessThan(10);
For a complete column use this:
worksheet.Column(1).AsRange().SetDataValidation().TextLength.EqualOrLessThan(10);
check this solution
notice that ErrorStyle and ErrorTitle are optional
worksheet.Range("A1", "A1").SetDataValidation().TextLength.EqualOrGreaterThan(5);
worksheet.Range("A1", "A1").SetDataValidation().ErrorStyle = ClosedXML.Excel.XLErrorStyle.Stop;
//XLErrorStyle.Stop will prevent adding data,
//XLErrorStyle.Information will show hint,
//XLErrorStyle.Warning will let user choose to continue or not
worksheet.Range("A1", "A1").SetDataValidation().ErrorTitle = "Text Length should be greater than 4 charachters";

conditional format excel epplus if (cell.value<0) fill red

I´m trying to apply conditional format to Excel using EPPLUS so that a range of cells is filled with red color if the value is negative.
I try this code that if the value of the cell is bigger that the value of the next cell, that cell is filled with red
ExcelAddress _formatRangeAddress = new ExcelAddress("J2:J"+(listaMargenes.Count+2));
string _statement="IF(OFFSET(J3,0,-1)-J3>0,1,0)";
var _cond4 = hoja.ConditionalFormatting.AddExpression(_formatRangeAddress);
_cond4.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_cond4.Style.Fill.BackgroundColor.Color = System.Drawing.Color.Red;
_cond4.Formula = _statement;
this Works fine, but if i change:
IF(OFFSET(J3,0,-1)-J3>0,1,0)
by this:
if(J3<0)
does not Works, when opening the Excel says there is corrupted data.
any idea of how to write the correct way tu put in red the cells with negative value?
An IF statement in excel does not allow for an optional value_if_true part anymore (I believe in older versions it did): MS IF Documentation
So change it to something like:
string _statement = "if(B3<0, 1)";

WPF FlowDocument space size is inconsistent

I'm using a FlowDocumentScrollViewer to print out log outputs to my application window, and am getting some rather weird spacing issues. Most of the spaces are correctly sized, but I'll consistently get way too large of spaces in some areas. Here's an example:
Correctly spaced: "d Copying E:\Projects"
What is displayed: "d Copying E:\Projects"
I had to use multiple spaces to reflect the spacing issue above, but I guarantee that it is indeed just displaying one space, incorrectly sized. This is easily verifiable by copying the text from my FlowDocumentScrollViewer into a text editor like notepad++. Here's the printing code for my simplest FlowDocumentScrollViewer:
LogBox.Document = new FlowDocument();
LogBox.Document.Background = LogBox.Background;
LogBox.Document.Foreground = LogBox.Foreground;
LogBox.Document.Blocks.Add(logParagraph = new Paragraph());
logParagraph.Margin = new Thickness(0); //Tested making Margin 0, didn't help
logParagraph.FontFamily = font;
logParagraph.FontSize = defaultFontSize;
...
public void PrintLog(String s)
{
logParagraph.Inlines.Add(s);
}
I've never seen anything like this, and searching for it on google is very difficult since everyone that uses "spacing" as a keyword really means line height... any help is appreciated.
Have you tried...
LogBox.TextAlignment = TextAlignment.Left;
and / or
logParagraph.TextAlignment = TextAlignment.Left;
owo? Because as I can see, in some cases the Block is getting an auto alignments to justify / stretch the text in the line~ Don't know why but seems to happen ;o
You could try adding a Run object in the PrintLog method, and modifying its properties like CharacterSpacing, and maybe try other ones as well. Sorry I don't have access to Visual Studio at the moment so I can't actually try it.
public void PrintLog(String s)
{
var run = new Run();
// modify run properties here
logParagraph.Inlines.Add(run);
}
You can view the MS documentation here: Run Class

Auto column width in EPPlus

How to make columns to be auto width when texts in columns are long?
I use this code
Worksheet.Column(colIndex).AutoFitColumn() 'on all columns'
Worksheet.cells.AutoFitColumns()
Worksheet.Column(colIndex).BestFit = True 'on all columns'
None of these methods are working
Are there any ways to make it work?
Note: Some of my texts use Unicode.
Use AutoFitColumns, but you have to specify the cells, i assume the entire worksheet:
VB.NET
Worksheet.Cells(Worksheet.Dimension.Address).AutoFitColumns()
C#
Worksheet.Cells[Worksheet.Dimension.Address].AutoFitColumns();
Please note you need to call this method after filling the worksheet.
I have used this code with the version 3.1.3.0 of EPPlus and it is working:
worksheet.Column(1).AutoFit();
where a worksheet is the variable referencing the worksheet I have created in my code (not a class with a static method!).
Obviously you have to call this method after you have filled the columns.
Just wanted to point out you can fit cells with out specifying the range, just make sure to call this after you've formatted all columns etc:
worksheet.Cells.AutoFitColumns()
I know this is an old question, but I use the code below and it seems to directly address what you have tried to do.
using (var xls = new ExcelPackage())
{
var ws = xls.Workbook.Worksheets.Add("Some Name");
//**Add Column Names to worksheet!**
//**Add data to worksheet!**
const double minWidth = 0.00;
const double maxWidth = 50.00;
ws.Cells.AutoFitColumns(minWidth, maxWidth);
return pkg.GetAsByteArray();
}
I know is a little bit late but I've had the same problem today. If you have a worksheet.DefaultColWidthdefined, it won't work. I've removed that line and added Worksheet.cells.AutoFitColumns(); and it works now.
It's working just fine for me.
Try:
ExcelWorksheet wsSheet1 = ExcelPkg.Workbook.Worksheets.Add("Sheet1");
wsSheet1.Cells[wsSheet1.Dimension.Address].AutoFitColumns();
ExcelPkg.SaveAs();
The .NET Core as a successor of .NET doesn't support anymore the function autofit cells with EPPplus library.
worksheet.Cells.AutoFitColumns();
or
worksheet.Column(1).AutoFit();
causes exception:
"System.Drawing is not supported on this platform."
The System.Drawing assembly is dependent on GDI and Windows specific libraries which have to be replaced by another solution. The solution for this issue is to me unknown.
Had to use worksheet.Column(1).AutoFit(0); AutoFit() wasn't doing the trick.
You will need to calculate the width. There is no autosizing function in the library that will work as you intend.
Autofitcolumn will not work with wrapped text and cells with formulas.
Look at http://epplus.codeplex.com/discussions/218294?ProjectName=epplus for examples of how you can solve the problem.
I use this and is working well.
Dim objExcel As New ExcelPackage
Dim Sheet As ExcelWorksheet = objExcel.Workbook.Worksheets.Add("SheetName")
Sheet.Cells("B1:BN").AutoFitColumns()

How to get cell value with applied formatting (formatted cell value) with OpenXML SDK

I've been googling and searching on the site for the answer, but I couldn't find a solution - everywhere people mostly discuss how to add new number format to the document and apply it.
What I need is to get the cell value as a string with applied formatting - i.e. same string as would be displayed by Excel.
I already figured that there's no easy way or built-in function which would return the readymade formatted value for a cell.
So it seems to me that to get the value I need to do two things:
1. Get the format string.
2. Format the cell value using this string.
But I have problems with both steps.
One can easily get CellFormat instance which would contain NumberFormatId:
CellFormat cellFormat = (CellFormat) document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.ElementAt(cell.StyleIndex);
But how to get the format string with this NumberFormatId, if the id corresponds to one of standard predefined formats? (i.e. is below 160) They are not in the spreadsheet document and I can't believe that they should be hardcoded in the application.
Also, once the format string is somehow obtained, how to apply it to the cell value? So far I understand, the code should check the type of the cell value and if is Number - convert it to string using the format string.
I found this page which mentions using Microsoft.Office.Excel.Interop, but I would prefer to stay with OpenXML SDK only.
Overall, I'm very surprised that it's so difficult to find a definitive answer to this question on the Web as I thought that this would be something which many developers need in their daily work.
Men, this is a hard one... I will be adding here things that i found that could be worth..
First is to get the numbering format of the cell (once you have the CellFormat:
string format = excel.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats.Elements<NumberingFormat>()
.Where(i => i.NumberFormatId.ToString() == cellFormat.NumberFormatId.ToString())
.First().FormatCode;
For more information about this you can go to: NumberingFormats
Im trying to find out how to apply this format to the cell.CellValue property... I think thats the way you have to go!
Ok, reading the ClosedXml code (its open source), seems to be easy to get the format.
Simply convert the value text to its type (int, double, etc) and call the ToString method passing the format. I was trying do that with the String.Format and didnt work. Ive tested the ToString and it works, but something still missing.
I recommend to you to look at this class and get the code from the method GetFormattedString() as #El G tell in his comment.
Bassicaly you will have to add something like this:
double d = double.Parse(cell.CellValue.InnerText);
string val = d.ToString(format);
Hope it helps you...
If you want to take cell value with applied formatting, same as displayed in Excel, use .Text property of Cell object. Like this:
String formattedValue = cell.Text

Categories

Resources