Unable to retrieve actual formula result in EPPLUS - epplus

I'm creating new .xlsx file using the template.xltx file. The template file(Template.xltx) contains Table and formulas. The Formula is added in .xltx file, in order to validate if the Table has data or not.
When I tried to retrieve the final result value at Cell[31,1], it is not returning the computed value. Instead it is returning the value that is in the template. Can you please help?
Template file:
EPPLus code:
FileInfo templateFile=new FileInfo("C:\\Template.xltx");
FileInfo excelFile=new FileInfo("C:\\Result.xlsx");
var package=new ExcelPackage(excelFile,templateFile);
package.Workbook.Worksheets[0].Cells[4, 1].Value = "test12";
package.Workbook.Worksheets[0].Cells[4, 2].Value = "1";
package.Workbook.Worksheets[0].Cells[4, 3].Value = "asfdf";
package.Workbook.Worksheets[0].Cells[4, 4].Value = "a333f";
package.Workbook.Worksheets[0].Cells[21, 1].Value = "test12";
package.Workbook.Worksheets[0].Cells[21, 2].Value = "1";
package.Workbook.Worksheets[0].Cells[21, 3].Value = "asfdf";
package.Workbook.Worksheets[0].Cells[21, 4].Value = "a333f";
ExcelCalculationOption option=new ExcelCalculationOption();
option.AllowCirculareReferences = true;
package.Workbook.Worksheets[0].Calculate(option);
package.Save();
Assert.AreEqual("Success", package.Workbook.Worksheets[0].Cells[31,1].Value);
package.Dispose();

See answer here: Setting *both* Value & Formula in EPPlus

Related

How to get NPOI Excel RichStringCellValue?

I am using DotNetCore.NPOI (1.2.1) in order to read an MS Excel file.
Some of the cells are of type text and contain formatted strings (e.g. some words in bold).
How do I get the formatted cell value? My final goal: Retrieve the cell text as HTML.
I tried
var cell = row.GetCell(1);
var richStringCellValue = cell.RichStringCellValue;
But this won't let me access the formatted string (just the plain string without formattings).
Does anybody have an idea or solution?
I think you'll have to take longer route in this case. First you'll have to maintain the formatting of cell value like date, currency etc and then extract the style from cell value and embed the cell value under that style.
best option is to write extenstion method to get format and style value.
To get the fomat Please see this link How to get the value of cell containing a date and keep the original formatting using NPOI
For styling first you'll have to check and find the exact style of running text and then return the value inside the html tag , below method will give you idea to extract styling from cell value. Code is untested , you may have to include missing library.
public void GetStyleOfCellValue()
{
XSSFWorkbook wb = new XSSFWorkbook("YourFile.xlsx");
ISheet sheet = wb.GetSheetAt(0);
ICell cell = sheet.GetRow(0).GetCell(0);
XSSFRichTextString richText = (XSSFRichTextString)cell.RichStringCellValue;
int formattingRuns = cell.RichStringCellValue.NumFormattingRuns;
for (int i = 0; i < formattingRuns; i++)
{
int startIdx = richText.GetIndexOfFormattingRun(i);
int length = richText.GetLengthOfFormattingRun(i);
Console.WriteLine("Text: " + richText.String.Substring(startIdx, startIdx + length));
if (i == 0)
{
short fontIndex = cell.CellStyle.FontIndex;
IFont font = wb.GetFontAt(fontIndex);
Console.WriteLine("Bold: " + (font.IsBold)); // return string <b>my string</b>.
Console.WriteLine("Italics: " + font.IsItalic + "\n"); // return string <i>my string</i>.
Console.WriteLine("UnderLine: " + font.Underline + "\n"); // return string <u>my string</u>.
}
else
{
IFont fontFormat = richText.GetFontOfFormattingRun(i);
Console.WriteLine("Bold: " + (fontFormat.IsBold)); // return string <b>my string</b>.
Console.WriteLine("Italics: " + fontFormat.IsItalic + "\n");// return string <i>my string</i>.
}
}
}
Font formatting in XLSX files are stored according to schema http://schemas.openxmlformats.org/spreadsheetml/2006/main which has no direct relationship to HTML tags. Therefore your task is not that much straight forward.
style = cell.getCellStyle();
font = style.getFont(); // or style.getFont(workBook);
// use Font object to query font attributes. E.g. font.IsItalic
Then you will have to build the HTML by appending relevant HTML tags.

Workbook cell style in POI/NPOI doesn't work properly with multiple styles in workbook

I'm running into strange problem with .Net version of POI library for Excel Spreadsheets. I'm rewriting from text files to Excel 97-2003 documents and I'm like to add some formatting programmatically depend on some values gather at the begging of the program.
At the beginning, in the same method where I was creating a new cell from given value I was creating also a new Workbook CellStyle which was wrong, because I was running out of the styles very quickly (or I was just thought it was the cause of the problem).
Constructor of the class responsible for Excel Workbook:
public OldExcelWriter(TextWriter logger) : base(logger)
{
_workbook = new HSSFWorkbook();
_sheetData = _workbook.CreateSheet("sheet1");
_creationHelper = _workbook.GetCreationHelper();
}
Method that is calling all the chains of operations:
public void Write(string path, Data data)
{
FillSpreadSheetWithData(data, _sheetData);
SaveSpreadSheet(_workbook, path);
}
Long story short, in FillSpreadSheetWithData I have method for creating a row inside which I'm have a loop for each cell, so basically I'm iterating thru every column, passing IRow references to a row, column value, index and formatting information like this:
for (int j = 0; j < column.Count; j++)
{
CreateCell(row, column[j], j, data.Formatting[j]);
}
and while creating a new styles (for first shot I was trying to pass some date time values) I had situation like this in my rewrited Excel: screenshot of excel workbook
So formatting was passed correctly (also Horizontal Aligment etc.) but it get ugly after 15th row (always the same amount).
DateTime dataCell = DateTime.MaxValue;
var cell = row.CreateCell(columnIndex);
_cellStyle = _workbook.CreateCellStyle();
switch (format.Type)
{
case DataType.Date:
_cellStyle.DataFormat = _creationHelper.CreateDataFormat().GetFormat("m/dd/yyyy");
if (value.Replace("\n", "") != string.Empty)
{
dataCell = DateTime.ParseExact(value.Replace("\n", ""), "m/dd/yyyy",
System.Globalization.CultureInfo.InvariantCulture);
}
break;
}
switch (format.HorizontalAlignment)
{
case Enums.HorizontalAlignment.Left:
_cellStyle.Alignment = HorizontalAlignment.LEFT;
break;
case Enums.HorizontalAlignment.Center:
_cellStyle.Alignment = HorizontalAlignment.CENTER;
break;
}
if (dataCell != DateTime.MaxValue)
{
cell.CellStyle = _cellStyle;
cell.SetCellValue(dataCell);
dataCell = DateTime.MaxValue;
}
else
{
cell.CellStyle = _cellStyle;
cell.SetCellValue(value);
}
(It's not the cleanest code but I will don refactor after getting this work).
After running into this issue I thought that maybe I will create _cellStyle variable in the constructor and only change it's value depends on the case, because it's assigned to the new cell anyway and I see while debugging that object values are correct.
But after creating everything, it won't get any better. Styles was override by the last value of the style, and dates are spoiled also, but later: screnshoot of excel workbook after creating one instance of cell style
I'm running out of ideas, maybe I should create every combination of the cell styles (I'm using only few data formats and alignments) but before I will do that (because I'm running out of easy options right now) I wonder what you guys think that should be done here.
cell format is set to custom with date type
I am using this code to create my custom style and format. Its for XSSF Format of excel sheet. but it will work for HSSF format with some modification.
XSSFFont defaultFont = (XSSFFont)workbook.CreateFont();
defaultFont.FontHeightInPoints = (short)10;
defaultFont.FontName = "Arial";
defaultFont.Color = IndexedColors.Black.Index;
defaultFont.IsBold = false;
defaultFont.IsItalic = false;
XSSFCellStyle dateCellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat dateDataFormat = (XSSFDataFormat)workbook.CreateDataFormat();
dateCellStyle.SetDataFormat(dateDataFormat.GetFormat("m/d/yy h:mm")); //Replace format by m/dd/yyyy. try similar approach for phone number etc.
dateCellStyle.FillBackgroundColor = IndexedColors.LightYellow.Index;
//dateCellStyle.FillPattern = FillPattern.NoFill;
dateCellStyle.FillForegroundColor = IndexedColors.LightTurquoise.Index;
dateCellStyle.FillPattern = FillPattern.SolidForeground;
dateCellStyle.Alignment = HorizontalAlignment.Left;
dateCellStyle.VerticalAlignment = VerticalAlignment.Top;
dateCellStyle.BorderBottom = BorderStyle.Thin;
dateCellStyle.BorderTop = BorderStyle.Thin;
dateCellStyle.BorderLeft = BorderStyle.Thin;
dateCellStyle.BorderRight = BorderStyle.Thin;
dateCellStyle.SetFont(defaultFont);
//Apply your style to column
_sheetData.SetDefaultColumnStyle(columnIndex, dateCellStyle);
// Or you can also apply style cell wise like
var row = _sheetData.CreateRow(0);
for (int cellIndex = 0;cellIndex < TotalHeaderCount;cellIndex++)
{
row.Cells[cellIndex].CellStyle = dateCellStyle;
}

How to write Google Sheets Script that searches my drive files for a variable search term entered in Cell B1 of my sheet?

I'm trying to write a google sheets script to search a series of my Drive files for a variable search term. My code works well as long as I consistently entitle my files that I want to search with "Joshs File". But I want to be able to search fullText by a variable search term entered in cell B1 of my sheet. What syntax do I use to do that?
fullText contains WHAT???
function SearchFiles() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = sheet.getSheets()[0];
var search0 = sh0.getRange("B1").getValue();
//Please enter your search term in the place of Letter
var searchFor = 'title contains "Joshs File"' + 'and fullText contains "X"';
var names =[];
var fileIds=[];
var files = DriveApp.searchFiles(searchFor);
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
names.push(name);
}
for (var i=0;i<names.length;i++){
Logger.log(names[i]);
}
var body = Logger.getLog();
var range=sh0.getRange("A5");
range.setValue(body);
}
Try using implementing this code:
function SearchFiles(){
var textString = "Sample";
var files = DriveApp.getFolderById(FolderID).searchFiles(
'fullText contains "'+textString+'"');
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
}
Just like how you concatenate a variable and string in JavaScript you have to use "+" in order for it to be recognized as a variable.
Hope this helps.

Autofitting column in combination with setting numberformat will autofit using unformatted text as measurement

When I use EPPlus to autofit a column that is formatted as a date string, the autofit mechanism is using the unformatted string as measurement for how wide the column should become.
Is it a bug or did I do something wrong?
Code
sheet.Column(2).Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
sheet.Cells.AutoFitColumns();
Result:
widening the second column in excel
Autofit using no formatting, notice that the second column is having the same width as the supposed-to-autofit column in the first picture.
For completion, here is the result when no autofit is used
It could be your font settings either in your code or globally in excel. Try running this test (I am posting this as an answer since I cannot fit it in a comment):
[TestMethod]
public void Auto_Col_Fomat_Test()
{
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[]
{
new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (DateTime)), new DataColumn("Col3", typeof (object))
});
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow();
row[0] = i; row[1] = DateTime.Now.AddDays(i); row[2] = Path.GetRandomFileName();
datatable.Rows.Add(row);
}
//Create a test file
var fi = new FileInfo(#"c:\temp\Auto_Col_Fomat.xlsx");
if (fi.Exists)
fi.Delete();
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var sheet = workbook.Worksheets.Add("Sheet1");
sheet.Cells.LoadFromDataTable(datatable, true);
sheet.Column(2).Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
sheet.Cells.AutoFitColumns();
pck.Save();
}
}
If this shows the same thing you may have changed your default excel font or zoom which means you may have to set the font in code to Body Font size 11 (at least that was 2013 uses). If it doesnt show post more of your code.
I had the same issue.
Here is my work around:
First call AutoFitColumns, then add some padding to the column that has a special format:
cells[sheet.Dimension.Address].AutoFitColumns();
sheet.Column(2).Width *= 1.25;

creating multiple pdfs from multiple excel files that support both formats in java

below is my code to convert excel to pdf, but i dont understand how do i generate multiple pdf from multiple excel sheets.
String files;
File folder = new File(dirpath);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
if (files.endsWith(".xls") || files.endsWith(".xlsx")) {
// inputting files one by one
//here it should take an input one by one
System.out.println(files);
String inputR = files.toString();
FileInputStream input_document = new FileInputStream(new File("D:\\ExcelToPdfProject\\"+inputR));
// Read workbook into HSSFWorkbook
Workbook workbook = null;
if (inputR.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(input_document);
System.out.println("1");
} else if (inputR.endsWith(".xls")) {
workbook = new HSSFWorkbook(input_document);
System.out.println("GO TO HELL ######");
} else {
System.out.println("GO TO HELL");
}
Sheet my_worksheet = workbook.getSheetAt(2);
// Read worksheet into HSSFSheet
// To iterate over the rows
Iterator<Row> rowIterator = my_worksheet.iterator();
//Iterator<Row> rowIterator1 = my_worksheet.iterator();
//We will create output PDF document objects at this point
Document iText_xls_2_pdf = new Document();
PdfWriter writer = PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("D:\\Output.pdf"));
iText_xls_2_pdf.open();
//we have two columns in the Excel sheet, so we create a PDF table with two columns
//Note: There are ways to make this dynamic in nature, if you want to.
Row row = rowIterator.next();
row.setHeight((short) 2);
int count = row.getPhysicalNumberOfCells();
PdfPTable my_table = new PdfPTable(count);
float[] columnWidths = new float[count];
my_table.setWidthPercentage(100f);
//We will use the object below to dynamically add new data to the table
PdfPCell table_cell;
I want something that can help me create a folder full of pdfs.