1802 lines
59 KiB
C#
1802 lines
59 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using Sarand.Net.Standard.Proc.Xml;
|
|
using Sarand.Net.Standard.Proc.Zip;
|
|
using NPOI.SS.UserModel;
|
|
using NPOI.XSSF.UserModel;
|
|
using NPOI.HSSF.UserModel;
|
|
using System.Linq;
|
|
using NPOI.SS.Formula.Functions;
|
|
using NPOI.SS.Util;
|
|
using System.Drawing;
|
|
using System.Security.Policy;
|
|
using MimeKit;
|
|
using DocumentFormat.OpenXml.Drawing.Charts;
|
|
using System.Reflection;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using NPOI.HSSF.Util;
|
|
using NPOI.XSSF.Model;
|
|
using System.Drawing.Imaging;
|
|
using System.Xml.Linq;
|
|
using EnumsNET;
|
|
using NPOI.OOXML.XSSF.UserModel;
|
|
|
|
namespace Sarand.Net.Standard.Proc.Excel
|
|
{
|
|
|
|
//=======================================================================
|
|
/// <summary>Excel spreadsheet as supported by NPOI.</summary>
|
|
public class SaMsSpreadsheet_POI : SaMsSpreadsheet
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Definitions.
|
|
|
|
//-------------------------------------------------------------------
|
|
// Data members.
|
|
private IWorkbook workbook;
|
|
private ISheet worksheet;
|
|
|
|
//-------------------------------------------------------------------
|
|
// Construction.
|
|
public SaMsSpreadsheet_POI() : base()
|
|
{
|
|
}
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
CloseWorkbook();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Properties.
|
|
|
|
//-------------------------------------------------------------------
|
|
// W o r k b o o k
|
|
//-------------------------------------------------------------------
|
|
public override bool IsWorkbookValid()
|
|
{
|
|
return workbook != null;
|
|
}
|
|
public override bool CreateWorkbook()
|
|
{
|
|
CloseWorkbook();
|
|
ClearErrorState();
|
|
|
|
// Create new workbook.
|
|
workbook = new XSSFWorkbook();
|
|
AddWorksheet("Sheet1");
|
|
return true;
|
|
}
|
|
public override bool OpenWorkbook(String filePath)
|
|
{
|
|
CloseWorkbook();
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
// Open workbook document.
|
|
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
|
{
|
|
try
|
|
{
|
|
// Open XML formats: xlsx etc.
|
|
workbook = new XSSFWorkbook(fs);
|
|
}
|
|
catch
|
|
{
|
|
// If reading fails, try to read workbook as XLS:
|
|
workbook = new HSSFWorkbook(fs);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
return OK;
|
|
}
|
|
public bool OpenWorkbook(byte[] workbookData)
|
|
{
|
|
CloseWorkbook();
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
using (MemoryStream workbookStream = new MemoryStream(workbookData))
|
|
{
|
|
OpenWorkbook(workbookStream);
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
return OK;
|
|
}
|
|
public bool OpenWorkbook(Stream workbookStream)
|
|
{
|
|
CloseWorkbook();
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
// From start of stream.
|
|
workbookStream.Seek(0, SeekOrigin.Begin);
|
|
// Open workbook document.
|
|
try
|
|
{
|
|
workbook = new XSSFWorkbook(workbookStream);
|
|
}
|
|
catch
|
|
{
|
|
// If reading fails, try to read workbook as XLS:
|
|
workbook = new HSSFWorkbook(workbookStream);
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>Cleanse workbook - remove unreferenced styles, fonts etc etc.</summary>
|
|
public override bool CleanseWorkbook()
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
if (workbook is HSSFWorkbook)
|
|
{
|
|
HSSFOptimiser.OptimiseCellStyles((HSSFWorkbook)workbook);
|
|
HSSFOptimiser.OptimiseFonts((HSSFWorkbook)workbook);
|
|
}
|
|
if (workbook is XSSFWorkbook)
|
|
{
|
|
// No equivalent XFFS functionality.
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(SysUtil.Fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>Save spreadsheet to file.</summary>
|
|
/// <param name="filePath"></param>
|
|
/// <param name="fileFormat">Ignored - depends on POI document version.</param>
|
|
/// <param name="bAutomaticallyOverwrite"></param>
|
|
/// <returns></returns>
|
|
public override bool SaveDocument(String filePath, int fileFormat, bool bAutomaticallyOverwrite)
|
|
{
|
|
ClearErrorState();
|
|
if (fileFormat == 0)
|
|
fileFormat = (int)XlFileFormat.xlOpenXMLWorkbook;
|
|
if (fileFormat != (int)XlFileFormat.xlOpenXMLWorkbook)
|
|
SetErrorState("Unsupported file format: " + ((XlFileFormat)fileFormat).ToString());
|
|
if (!HasErrorState() && !IsWorkbookValid())
|
|
SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!HasErrorState())
|
|
{
|
|
try
|
|
{
|
|
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
|
{
|
|
workbook.Write(fs);
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool CloseWorkbook()
|
|
{
|
|
ClearErrorState();
|
|
CloseWorksheet();
|
|
// Clear workbook.
|
|
if (workbook != null)
|
|
workbook = null;
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>Extract the document as a byte array.</summary>
|
|
/// <returns>Document data as byte array.</returns>
|
|
public override byte[] GetDocumentData()
|
|
{
|
|
ClearErrorState();
|
|
if (!HasErrorState() && !IsWorkbookValid())
|
|
SetErrorState(Msg_WorkbookNotOpen);
|
|
|
|
if (!HasErrorState())
|
|
{
|
|
try
|
|
{
|
|
using (MemoryStream memStream = new MemoryStream())
|
|
{
|
|
workbook.Write(memStream);
|
|
return memStream.ToArray();
|
|
}
|
|
}
|
|
catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Default style.
|
|
public override void ApplyDefaultStyle(SaMsExcelStyleAttr attr)
|
|
{
|
|
try
|
|
{
|
|
// Zero font.
|
|
IFont font = workbook.GetFontAt(0);
|
|
ApplyFontAttr(font, attr);
|
|
// Zero style - is this the default for all cells?.
|
|
ICellStyle style = workbook.GetCellStyleAt(0);
|
|
ApplyAttrToCellStyle(attr, style);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// W o r k s h e e t s
|
|
//-------------------------------------------------------------------
|
|
// Worksheet count.
|
|
public override uint WorksheetCount { get { return (uint)workbook.NumberOfSheets; } }
|
|
public override bool SetWorksheetCount(int worksheetCount)
|
|
{
|
|
ClearErrorState();
|
|
ClearErrorState();
|
|
if (worksheetCount > 0 && worksheetCount < 11)
|
|
{
|
|
while (WorksheetCount < worksheetCount)
|
|
AddWorksheet("");
|
|
while (WorksheetCount > worksheetCount)
|
|
RemoveWorksheet(WorksheetCount);
|
|
OpenWorksheet(1);
|
|
}
|
|
else SetErrorState(SysUtil.Fn + " - Requested number of worksheets (" + worksheetCount.ToString() + ") must be between 1 and 10");
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Worksheet names.
|
|
public override List<String> WorksheetNames
|
|
{
|
|
get
|
|
{
|
|
ClearErrorState();
|
|
HashSet<String> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
if (!HasErrorState() && !IsWorkbookValid())
|
|
SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!HasErrorState())
|
|
{
|
|
for (int sheetPos = 1; sheetPos <= workbook.NumberOfSheets; sheetPos++)
|
|
names.Add(workbook.GetSheetName(sheetPos));
|
|
}
|
|
return new List<String>(names);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Add worksheet.
|
|
public override bool AddWorksheet(String name)
|
|
{
|
|
ClearErrorState();
|
|
if (!HasErrorState() && !IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
CloseWorksheet();
|
|
|
|
// Determine name for sheet.
|
|
if (StringUtil.IsBlank(name))
|
|
{
|
|
List<String> sheetNames = WorksheetNames;
|
|
for (int sheetPos = 1; sheetPos <= workbook.NumberOfSheets; sheetPos++)
|
|
{
|
|
name = "Sheet " + sheetPos;
|
|
if (!sheetNames.ContainsCI(name))
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Add a blank sheet.
|
|
worksheet = workbook.CreateSheet(name);
|
|
return IsWorksheetValid();
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Remove worksheet.
|
|
/// <para>Worksheet 0 is the currently open sheet.</para>
|
|
/// </summary>
|
|
public override bool RemoveWorksheet(uint worksheetPos = 0)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
try
|
|
{
|
|
if (worksheetPos > WorksheetCount)
|
|
return SetErrorState("Worksheet position must be up to " + WorksheetCount);
|
|
if (worksheetPos < 1)
|
|
{
|
|
// Worksheet '0' is the current sheet.
|
|
if (worksheet != null)
|
|
worksheetPos = (uint)(workbook.GetSheetIndex(worksheet) + 1);
|
|
else return SetErrorState("Worksheet position '0' not available - no open worksheet.");
|
|
}
|
|
int worksheetIdx = ((int)worksheetPos) - 1;
|
|
|
|
if (worksheet != null)
|
|
{
|
|
// Retrieve specified sheet to compare to currently open sheet.
|
|
ISheet sheet = workbook.GetSheetAt(worksheetIdx);
|
|
// Only close current sheet if it's about to be removed.
|
|
if (sheet.SheetName.EqualsCI(worksheet.SheetName))
|
|
CloseWorksheet();
|
|
}
|
|
workbook.RemoveSheetAt(worksheetIdx);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// W o r k s h e e t
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Open worksheet by position (from 1).
|
|
/// <para>Worksheet 0 is the currently open sheet or first if none open.</para>
|
|
/// </summary>
|
|
public override bool OpenWorksheet(uint worksheetPos)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid()) return SetErrorState(Msg_WorkbookNotOpen);
|
|
try
|
|
{
|
|
if (worksheetPos > WorksheetCount)
|
|
return SetErrorState("Worksheet position must be up to " + WorksheetCount);
|
|
if (worksheetPos < 1)
|
|
{
|
|
// Worksheet '0' is the current sheet.
|
|
if (worksheet != null)
|
|
worksheetPos = (uint)(workbook.GetSheetIndex(worksheet) + 1);
|
|
else worksheetPos = 1;
|
|
}
|
|
int worksheetIdx = ((int)worksheetPos) - 1;
|
|
|
|
// Open worksheet.
|
|
CloseWorksheet();
|
|
worksheet = workbook.GetSheetAt(worksheetIdx);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>Open worksheet by name (case and whitespace insensitive).</summary>
|
|
public override bool OpenWorksheet(String name)
|
|
{
|
|
ClearErrorState();
|
|
name = StringUtil.TrimWhitespace(StringUtil.OnBlank(name));
|
|
if (!IsWorkbookValid()) return SetErrorState(Msg_WorkbookNotOpen);
|
|
try
|
|
{
|
|
// Open worksheet.
|
|
for (int worksheetIdx = 0; worksheetIdx < workbook.NumberOfSheets; worksheetIdx++)
|
|
{
|
|
ISheet worksheetCandidate = workbook.GetSheetAt(worksheetIdx);
|
|
if (StringUtil.TrimWhitespace(worksheetCandidate.SheetName).EqualsCI(name))
|
|
{
|
|
CloseWorksheet();
|
|
worksheet = worksheetCandidate;
|
|
return true;
|
|
}
|
|
}
|
|
SetErrorState("Worksheet not found.");
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Close currently open worksheet.
|
|
public override bool CloseWorksheet()
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (worksheet != null)
|
|
worksheet = null;
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool IsWorksheetValid()
|
|
{
|
|
if (!IsWorkbookValid()) return false;
|
|
return worksheet != null;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override uint WorksheetPos { get { return (uint)(workbook.GetSheetIndex(worksheet) + 1); } }
|
|
public override String WorksheetName
|
|
{
|
|
get { return worksheet?.SheetName ?? ""; }
|
|
set { workbook.SetSheetName(workbook.GetSheetIndex(worksheet), value); }
|
|
}
|
|
public override bool SetWorksheetAttr(SaMsExcelStyleAttr attr)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!IsWorksheetValid())
|
|
return SetErrorState("Worksheet is not open");
|
|
return SetErrorState(SysUtil.Fn + " " + Msg_NotSupported);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Worksheet Page Setup.
|
|
public override bool SetPageSetup(SaMsExcelPageSetup_Config pageSetupConfig)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!IsWorksheetValid())
|
|
return SetErrorState("Worksheet is not open");
|
|
//---------------------------------------------------------------
|
|
// Page setup options:
|
|
// ActiveSheet.PageSetup
|
|
// .PrintTitleRows = "$4:$4"
|
|
// .PrintTitleColumns = ""
|
|
// .PrintArea = ""
|
|
// .LeftHeader = ""
|
|
// .CenterHeader = ""
|
|
// .RightHeader = ""
|
|
// .LeftFooter = ""
|
|
// .CenterFooter = ""
|
|
// .RightFooter = ""
|
|
// .LeftMargin = Application.InchesToPoints(0.708661417322835)
|
|
// .RightMargin = Application.InchesToPoints(0.708661417322835)
|
|
// .TopMargin = Application.InchesToPoints(0.748031496062992)
|
|
// .BottomMargin = Application.InchesToPoints(0.748031496062992)
|
|
// .HeaderMargin = Application.InchesToPoints(0.31496062992126)
|
|
// .FooterMargin = Application.InchesToPoints(0.31496062992126)
|
|
// .PrintHeadings = False
|
|
// .PrintGridlines = False
|
|
// .PrintComments = xlPrintNoComments
|
|
// .PrintQuality = 600
|
|
// .CenterHorizontally = False
|
|
// .CenterVertically = False
|
|
// .Orientation = xlPortrait
|
|
// .Draft = False
|
|
// .PaperSize = xlPaperA4
|
|
// .FirstPageNumber = xlAutomatic
|
|
// .Order = xlDownThenOver
|
|
// .BlackAndWhite = False
|
|
// .Zoom = 100
|
|
// .PrintErrors = xlPrintErrorsDisplayed
|
|
// .OddAndEvenPagesHeaderFooter = False
|
|
// .DifferentFirstPageHeaderFooter = False
|
|
// .ScaleWithDocHeaderFooter = True
|
|
// .AlignMarginsHeaderFooter = True
|
|
// .EvenPage.LeftHeader.Text = ""
|
|
// .EvenPage.CenterHeader.Text = ""
|
|
// .EvenPage.RightHeader.Text = ""
|
|
// .EvenPage.LeftFooter.Text = ""
|
|
// .EvenPage.CenterFooter.Text = ""
|
|
// .EvenPage.RightFooter.Text = ""
|
|
// .FirstPage.LeftHeader.Text = ""
|
|
// .FirstPage.CenterHeader.Text = ""
|
|
// .FirstPage.RightHeader.Text = ""
|
|
// .FirstPage.LeftFooter.Text = ""
|
|
// .FirstPage.CenterFooter.Text = ""
|
|
// .FirstPage.RightFooter.Text = ""
|
|
//---------------------------------------------------------------
|
|
// Negative values leave current value.
|
|
try
|
|
{
|
|
// Print setup.
|
|
IPrintSetup printSetup = worksheet.PrintSetup;
|
|
|
|
if (pageSetupConfig.Orientation == SaXlPageOrientation.xlLandscape)
|
|
printSetup.Landscape = true;
|
|
else if (pageSetupConfig.Orientation == SaXlPageOrientation.xlPortrait)
|
|
printSetup.Landscape = false;
|
|
|
|
// Headers and footers.
|
|
worksheet.Header.Left = pageSetupConfig.HeaderLeft;
|
|
worksheet.Header.Center = pageSetupConfig.HeaderCenter;
|
|
worksheet.Header.Right = pageSetupConfig.HeaderRight;
|
|
worksheet.Footer.Left = pageSetupConfig.FooterLeft;
|
|
worksheet.Footer.Center = pageSetupConfig.FooterCenter;
|
|
worksheet.Footer.Right = pageSetupConfig.FooterRight;
|
|
|
|
// Margins.
|
|
if (pageSetupConfig.MarginLeft > 0)
|
|
worksheet.SetMargin(MarginType.LeftMargin, ToPoints(pageSetupConfig.MarginLeft, pageSetupConfig.Unit, false));
|
|
if (pageSetupConfig.MarginRight > 0)
|
|
worksheet.SetMargin(MarginType.RightMargin, ToPoints(pageSetupConfig.MarginRight, pageSetupConfig.Unit, false));
|
|
if (pageSetupConfig.MarginTop > 0)
|
|
worksheet.SetMargin(MarginType.TopMargin, ToPoints(pageSetupConfig.MarginTop, pageSetupConfig.Unit, false));
|
|
if (pageSetupConfig.MarginBottom > 0)
|
|
worksheet.SetMargin(MarginType.BottomMargin, ToPoints(pageSetupConfig.MarginBottom, pageSetupConfig.Unit, false));
|
|
if (pageSetupConfig.MarginHeader > 0)
|
|
worksheet.SetMargin(MarginType.HeaderMargin, ToPoints(pageSetupConfig.MarginHeader, pageSetupConfig.Unit, false));
|
|
if (pageSetupConfig.MarginFooter > 0)
|
|
worksheet.SetMargin(MarginType.FooterMargin, ToPoints(pageSetupConfig.MarginFooter, pageSetupConfig.Unit, false));
|
|
|
|
// Print Title Rows.
|
|
if (pageSetupConfig.PrintTitleRowFrom > 0 && pageSetupConfig.PrintTitleRowTo > 0)
|
|
{
|
|
// Prefix with '$' to fix row value.(?)
|
|
worksheet.RepeatingRows = CellRangeAddress.ValueOf(pageSetupConfig.PrintTitleRowFrom + ":" + pageSetupConfig.PrintTitleRowTo);
|
|
}
|
|
else if (pageSetupConfig.PrintTitleRowFrom == 0 && pageSetupConfig.PrintTitleRowTo == 0)
|
|
worksheet.RepeatingRows = null;
|
|
|
|
// Print Title Columns.
|
|
if (pageSetupConfig.PrintTitleColFrom > 0 && pageSetupConfig.PrintTitleColTo > 0)
|
|
worksheet.RepeatingColumns = CellRangeAddress.ValueOf(pageSetupConfig.PrintTitleColFrom + ":" + pageSetupConfig.PrintTitleColTo);
|
|
else if (pageSetupConfig.PrintTitleColFrom == 0 && pageSetupConfig.PrintTitleColTo == 0)
|
|
worksheet.RepeatingColumns = null;
|
|
|
|
// Zoom & 'Fit to' options.
|
|
if (pageSetupConfig.Zoom > 0)
|
|
worksheet.SetZoom(pageSetupConfig.Zoom);
|
|
else if (pageSetupConfig.FitToPagesTall > 0 || pageSetupConfig.FitToPagesWide > 0)
|
|
{
|
|
worksheet.SetZoom(0);
|
|
worksheet.FitToPage = false;
|
|
printSetup.FitWidth = (short)Math.Min(0, pageSetupConfig.FitToPagesWide);
|
|
printSetup.FitHeight = (short)Math.Min(0, pageSetupConfig.FitToPagesTall);
|
|
}
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Page breaks.
|
|
public override bool SetPageBreak(uint col, uint row)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid())
|
|
return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!IsWorksheetValid())
|
|
return SetErrorState("Worksheet is not open");
|
|
try
|
|
{
|
|
worksheet.FitToPage = false;
|
|
worksheet.SetColumnBreak((int)(col - 1));
|
|
worksheet.SetRowBreak((int)(row - 1));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
HandleException(SysUtil.Fn, exc);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// C o l u m n s
|
|
//-------------------------------------------------------------------
|
|
public override uint ActiveColPos { get { return (uint)(worksheet.ActiveCell.Column + 1); } }
|
|
public override double GetColWidth(uint colPos, SaExcelLogicalUnit unit = SaExcelLogicalUnit.Point)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid()) SetErrorState(Msg_WorkbookNotOpen);
|
|
else if (!IsWorksheetValid()) SetErrorState("Worksheet is not open");
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// Retrieve width (in points) from column.
|
|
double width = worksheet.GetColumnWidth((int)(colPos - 1));
|
|
// Adjust for units.
|
|
if (unit == SaExcelLogicalUnit.Pixel) return PointsToPixels(width, false);
|
|
if (unit == SaExcelLogicalUnit.Cm) return PointsToCms(width);
|
|
if (unit == SaExcelLogicalUnit.Inch) return PointsToInches(width);
|
|
return width;
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
}
|
|
return 0.0;
|
|
}
|
|
/// <summary> Default xcharacter width in pixels. </summary>
|
|
private static readonly double DEFAULT_CHARACTER_WIDTH = 7.001699924468994f; /* From Apache POI) */
|
|
public override bool SetColWidth(uint colPos, double width, SaExcelLogicalUnit unit = SaExcelLogicalUnit.Point)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid()) return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!IsWorksheetValid()) return SetErrorState("Worksheet is not open");
|
|
try
|
|
{
|
|
// Adjust for units.
|
|
double widthPixels = ConvertLength(width, unit, SaExcelLogicalUnit.Pixel, false);
|
|
// POI units for column width are 1/256th default character width.
|
|
// Ref. NPOI.Util.Units
|
|
worksheet.SetColumnWidth((int)(colPos - 1), (int)Math.Ceiling(widthPixels * 256 / DEFAULT_CHARACTER_WIDTH));
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// R o w s
|
|
//-------------------------------------------------------------------
|
|
public override uint FirstRowPos { get { return (uint)(worksheet.FirstRowNum + 1); } }
|
|
public override uint LastRowPos { get { return (uint)(worksheet.LastRowNum + 1); } }
|
|
|
|
//-------------------------------------------------------------------
|
|
private IRow GetRowByIdx(int rowIdx, bool create = false)
|
|
{
|
|
IRow row = worksheet.GetRow(rowIdx);
|
|
if (row == null && create)
|
|
row = worksheet.CreateRow(rowIdx);
|
|
return row;
|
|
}
|
|
|
|
private IRow GetRowByPos(uint rowPos, bool create = false)
|
|
{
|
|
return GetRowByIdx((int)(rowPos - 1), create);
|
|
}
|
|
|
|
public int ActiveRowIdx { get { return worksheet.ActiveCell.Row; } }
|
|
public override uint ActiveRowPos { get { return (uint)(ActiveRowIdx + 1); } }
|
|
|
|
//-------------------------------------------------------------------
|
|
public override double GetRowHeight(uint rowPos, SaExcelLogicalUnit unit = SaExcelLogicalUnit.Point)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid()) SetErrorState(Msg_WorkbookNotOpen);
|
|
else if (!IsWorksheetValid()) SetErrorState("Worksheet is not open");
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// Retrieve height (in points) from row.
|
|
IRow row = GetRowByPos(rowPos);
|
|
double height = row?.Height ?? 0.0;
|
|
// Adjust for units.
|
|
if (unit == SaExcelLogicalUnit.Pixel) return PointsToPixels(height, true);
|
|
if (unit == SaExcelLogicalUnit.Cm) return PointsToCms(height);
|
|
if (unit == SaExcelLogicalUnit.Inch) return PointsToInches(height);
|
|
return height;
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
}
|
|
return 0.0;
|
|
}
|
|
public override bool SetRowHeight(uint rowPos, double height, SaExcelLogicalUnit unit = SaExcelLogicalUnit.Point)
|
|
{
|
|
ClearErrorState();
|
|
if (!IsWorkbookValid()) return SetErrorState(Msg_WorkbookNotOpen);
|
|
if (!IsWorksheetValid()) return SetErrorState("Worksheet is not open");
|
|
try
|
|
{
|
|
// Adjust for units.
|
|
if (unit == SaExcelLogicalUnit.Pixel) height = PixelsToPoints(height, true);
|
|
if (unit == SaExcelLogicalUnit.Cm) height = CmsToPoints(height);
|
|
if (unit == SaExcelLogicalUnit.Inch) height = InchesToPoints(height);
|
|
// Set row height.
|
|
IRow row = GetRowByPos(rowPos, true);
|
|
row.Height = (short)height;
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override List<DataValue> GetRowValues(uint rowPos, int maxColumns = 0)
|
|
{
|
|
ClearErrorState();
|
|
List<DataValue> values = new List<DataValue>();
|
|
try
|
|
{
|
|
IRow row = GetRowByPos(rowPos);
|
|
if (row != null)
|
|
{
|
|
foreach (ICell cell in row.Cells)
|
|
{
|
|
values.Add(GetCellDataValue(cell));
|
|
if (maxColumns > 0 && values.Count >= maxColumns) break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return values;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// C e l l s
|
|
//-------------------------------------------------------------------
|
|
private ICell GetCell(uint colPos, uint rowPos, bool create = false)
|
|
{
|
|
ClearErrorState();
|
|
IRow row = GetRowByPos(rowPos, create);
|
|
return GetCell(colPos, row, create);
|
|
}
|
|
|
|
private ICell GetCell(uint colPos, IRow row, bool createBlank = false)
|
|
{
|
|
ClearErrorState();
|
|
ICell cell = row?.GetCell((int)(colPos - 1), createBlank ? MissingCellPolicy.CREATE_NULL_AS_BLANK : MissingCellPolicy.RETURN_NULL_AND_BLANK);
|
|
if (cell != null && (cell.CellStyle == null || cell.CellStyle.Index == 0))
|
|
{
|
|
ICellStyle colStyle = worksheet.GetColumnStyle(cell.ColumnIndex);
|
|
if (colStyle.Index != 0)
|
|
cell.CellStyle = colStyle;
|
|
}
|
|
return cell;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override void SetActiveCell(uint colPos, uint rowPos)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
worksheet.ActiveCell = new CellAddress((int)(rowPos - 1), (int)(colPos - 1));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
HandleException(SysUtil.Fn, exc);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private bool IsCellFormula(uint colPos, uint rowPos)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
return IsCellFormula(cell);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return false;
|
|
}
|
|
private bool IsCellFormula(ICell cell)
|
|
{
|
|
return cell != null && cell.CellType == NPOI.SS.UserModel.CellType.Formula;
|
|
}
|
|
private bool IsCellNumeric(uint colPos, uint rowPos)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
return IsCellNumeric(cell);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return false;
|
|
}
|
|
private bool IsCellNumeric(ICell cell)
|
|
{
|
|
return cell != null && cell.CellType == NPOI.SS.UserModel.CellType.Numeric;
|
|
}
|
|
private bool IsCellDate(uint colPos, uint rowPos)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
return IsCellDate(cell);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return false;
|
|
}
|
|
private bool IsCellDate(ICell cell)
|
|
{
|
|
return cell != null && NPOI.SS.UserModel.DateUtil.IsCellDateFormatted(cell);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override String GetCellFormula(uint colPos, uint rowPos)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
String formula = "";
|
|
if (cell != null)
|
|
{
|
|
if (IsCellFormula(cell))
|
|
formula = cell.CellFormula;
|
|
if (StringUtil.IsEmpty(formula) && cell != null)
|
|
formula = GetCellText(cell, true);
|
|
}
|
|
return formula;
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return "";
|
|
}
|
|
|
|
public override String GetCellText(uint colPos, uint rowPos, bool trimWhitespace = true)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
return cell != null ? GetCellText(cell, true) : "";
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return "";
|
|
}
|
|
|
|
private String GetCellText(ICell cell, bool trimValue = true)
|
|
{
|
|
ClearErrorState();
|
|
String value = "";
|
|
try
|
|
{
|
|
value = cell.ToString();
|
|
if (trimValue) value.TrimAll();
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return value;
|
|
}
|
|
|
|
public override DataValue GetCellValue(uint colPos, uint rowPos)
|
|
{
|
|
return GetCellDataValue(GetCell(colPos, rowPos), false);
|
|
}
|
|
private DataValue GetCellDataValue(ICell cell, bool trimTextValue = true)
|
|
{
|
|
ClearErrorState();
|
|
try
|
|
{
|
|
if (IsCellDate(cell))
|
|
{
|
|
// Ref. https://stackoverflow.com/questions/23280533/apache-poi-getting-a-null-pointer-while-reading-a-cell-with-value
|
|
// recommends using DateTime.FromOADate(cell.NumericCellValue) rather than cell.DateCellValue
|
|
return new DataValue(cell.DateCellValue);
|
|
}
|
|
if (IsCellNumeric(cell))
|
|
{
|
|
double value = cell.NumericCellValue;
|
|
if (Math.Floor(value) == value)
|
|
return new DataValue((long)value);
|
|
else
|
|
return new DataValue(value);
|
|
}
|
|
return new DataValue(cell.StringCellValue);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
HandleException(SysUtil.Fn, exc);
|
|
}
|
|
return new DataValue();
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool SetCellFormula(uint colPos, uint rowPos, String value, SaMsExcelStyleAttr attr)
|
|
{
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos, true);
|
|
cell.CellFormula = value;
|
|
// Set cell attributes (style etc).
|
|
SaMsExcelRange range = new SaMsExcelRange(colPos, rowPos);
|
|
SetRangeAttr(range, attr);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
public override bool SetCellValue(uint colPos, uint rowPos, DataValue value, SaMsExcelStyleAttr attr)
|
|
{
|
|
try
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos, true);
|
|
SetCellValue(cell, value);
|
|
// Set cell attributes (style etc).
|
|
SaMsExcelRange range = new SaMsExcelRange(colPos, rowPos);
|
|
SetRangeAttr(range, attr);
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private void SetCellValue(ICell cell, Object value)
|
|
{
|
|
if (value == null)
|
|
cell.SetBlank();
|
|
else if (value is bool)
|
|
cell.SetCellValue((bool)value);
|
|
else if (value is short)
|
|
cell.SetCellValue((short)value);
|
|
else if (value is int)
|
|
cell.SetCellValue((int)value);
|
|
else if (value is long)
|
|
cell.SetCellValue((long)value);
|
|
else if (value is float)
|
|
cell.SetCellValue((float)value);
|
|
else if (value is double)
|
|
cell.SetCellValue((double)value);
|
|
else if (value is DateTime)
|
|
cell.SetCellValue((DateTime)value);
|
|
else
|
|
cell.SetCellValue(value.ToString());
|
|
}
|
|
|
|
private void SetCellValue(ICell cell, DataValue value)
|
|
{
|
|
if (value == null)
|
|
cell.SetBlank();
|
|
// Populate cell value based on value type.
|
|
switch (value.GetDataType())
|
|
{
|
|
case DataValue.DataType.Bool:
|
|
cell.SetCellValue(value.AsBool());
|
|
break;
|
|
case DataValue.DataType.Long:
|
|
cell.SetCellValue(value.AsLong());
|
|
break;
|
|
case DataValue.DataType.Double:
|
|
cell.SetCellValue(value.AsDouble());
|
|
break;
|
|
case DataValue.DataType.Decimal:
|
|
cell.SetCellValue((double)value.AsDecimal());
|
|
break;
|
|
case DataValue.DataType.Date:
|
|
cell.SetCellValue(value.AsDate());
|
|
break;
|
|
case DataValue.DataType.Time:
|
|
cell.SetCellValue(value.AsTime());
|
|
break;
|
|
case DataValue.DataType.DateTime:
|
|
cell.SetCellValue(value.AsDateTime());
|
|
break;
|
|
default:
|
|
cell.SetCellValue(value.ToString());
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool SetRowFormulas(uint colPosStart, uint rowPos, List<String> values)
|
|
{
|
|
try
|
|
{
|
|
IRow row = GetRowByPos(rowPos, true);
|
|
for (Math.Max(1, colPosStart); colPosStart <= values.Count; colPosStart++)
|
|
{
|
|
Object value = values[(int)(colPosStart - 1)];
|
|
ICell cell = GetCell(colPosStart, row, true);
|
|
SetCellValue(cell, value);
|
|
}
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
public override bool SetRowValues(uint colPosStart, uint rowPos, List<DataValue> values)
|
|
{
|
|
try
|
|
{
|
|
IRow row = GetRowByPos(rowPos, true);
|
|
for (int valueIdx = 0; valueIdx < values.Count; valueIdx++)
|
|
{
|
|
uint colPos = (uint)Math.Max(1, colPosStart + valueIdx);
|
|
Object value = values[valueIdx];
|
|
ICell cell = GetCell(colPos, row, true);
|
|
SetCellValue(cell, value);
|
|
}
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private void EvaluateAllFormulaCells()
|
|
{
|
|
if (workbook is XSSFWorkbook)
|
|
XSSFFormulaEvaluator.EvaluateAllFormulaCells(workbook);
|
|
else
|
|
HSSFFormulaEvaluator.EvaluateAllFormulaCells(workbook);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// C e l l S t y l e
|
|
//-------------------------------------------------------------------
|
|
private String GetBuiltInStyleFormat(int numFmtId)
|
|
{
|
|
// Ref. http://stackoverflow.com/questions/4730152/what-indicates-an-office-open-xml-cell-contains-a-date-time-value
|
|
switch (numFmtId)
|
|
{
|
|
//
|
|
case 0: return "General";
|
|
case 1: return "0";
|
|
case 2: return "0.00";
|
|
case 3: return "#,##0";
|
|
case 4: return "#,##0.00";
|
|
//
|
|
case 9: return "0%";
|
|
case 10: return "0.00%";
|
|
case 11: return "0.00E+00";
|
|
case 12: return "# ?/?";
|
|
case 13: return "# ??/??";
|
|
case 14: return "mm-dd-yy";
|
|
case 15: return "d-mmm-yy";
|
|
case 16: return "d-mmm";
|
|
case 17: return "mmm-yy";
|
|
case 18: return "h:mm AM/PM";
|
|
case 19: return "h:mm:ss AM/PM";
|
|
case 20: return "h:mm";
|
|
case 21: return "h:mm:ss";
|
|
case 22: return "m/d/yy h:mm";
|
|
//
|
|
case 37: return "#,##0 ;(#,##0)";
|
|
case 38: return "#,##0 ;[Red](#,##0)";
|
|
case 39: return "#,##0.00;(#,##0.00)";
|
|
case 40: return "#,##0.00;[Red](#,##0.00)";
|
|
//
|
|
case 44: return "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)";
|
|
case 45: return "mm:ss";
|
|
case 46: return "[h]:mm:ss";
|
|
case 47: return "mmss.0";
|
|
case 48: return "##0.0E+0";
|
|
case 49: return "@";
|
|
//
|
|
case 27: return "[$-404]e/m/d";
|
|
case 30: return "m/d/yy";
|
|
case 36: return "[$-404]e/m/d";
|
|
case 50: return "[$-404]e/m/d";
|
|
case 57: return "[$-404]e/m/d";
|
|
//
|
|
case 59: return "t0";
|
|
case 60: return "t0.00";
|
|
case 61: return "t#,##0";
|
|
case 62: return "t#,##0.00";
|
|
case 67: return "t0%";
|
|
case 68: return "t0.00%";
|
|
case 69: return "t# ?/?";
|
|
case 70: return "t# ??/??";
|
|
}
|
|
return "";
|
|
}
|
|
private bool IsDateStyle(String numFormat)
|
|
{
|
|
// Ref. http://stackoverflow.com/questions/19034805/how-to-distinguish-inline-numbers-from-ole-automation-date-numbers-in-openxml-sp/19582685#19582685
|
|
if (IsTimeStyle(numFormat)) return false;
|
|
if (numFormat.Contains("d")) return true;
|
|
if (numFormat.Contains("m")) return true;
|
|
if (numFormat.Contains("y")) return true;
|
|
return false;
|
|
}
|
|
private bool IsTimeStyle(String numFormat)
|
|
{
|
|
if (numFormat.Contains("h")) return true;
|
|
if (numFormat.Contains(":mm")) return true;
|
|
if (numFormat.Contains("mm:")) return true;
|
|
if (numFormat.Contains(":ss")) return true;
|
|
return false;
|
|
}
|
|
private bool IsDateTimeStyle(String numFormat)
|
|
{
|
|
return (IsDateStyle(numFormat) || IsTimeStyle(numFormat));
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Cell attributes.
|
|
public override bool SetRangeAttr(SaMsExcelRange range, SaMsExcelStyleAttr attr)
|
|
{
|
|
if (attr == null) return false;
|
|
try
|
|
{
|
|
// Apply style to cells.
|
|
for (uint rowPos = range.RowFromPos; rowPos <= range.RowToPos; rowPos++)
|
|
{
|
|
IRow row = null;
|
|
if (rowPos > 0)
|
|
row = GetRowByPos(rowPos, true);
|
|
for (uint colPos = range.ColFromPos; colPos <= range.ColToPos; colPos++)
|
|
{
|
|
if (rowPos < 1 && colPos < 1)
|
|
{
|
|
// Style is to be aplied to entire sheet.
|
|
}
|
|
else if (rowPos < 1)
|
|
{
|
|
// Style is to be applied to entire column.
|
|
ICellStyle colStyle = worksheet.GetColumnStyle((int)(colPos - 1));
|
|
if (colStyle != null && colStyle.Index != 0)
|
|
{
|
|
// Column already has its own specific stlying.
|
|
ApplyAttrToCellStyle(attr, colStyle);
|
|
worksheet.SetDefaultColumnStyle((int)(colPos - 1), colStyle);
|
|
}
|
|
else
|
|
{
|
|
// Create specific styling for column.
|
|
colStyle = CloneCellStyle(colStyle);
|
|
ApplyAttrToCellStyle(attr, colStyle);
|
|
worksheet.SetDefaultColumnStyle((int)(colPos - 1), colStyle);
|
|
}
|
|
// Apply style to existing cells in column.
|
|
for (uint colRowPos = FirstRowPos; colRowPos <= LastRowPos; colRowPos++)
|
|
{
|
|
ICell cell = GetCell(colPos, colRowPos, false);
|
|
ApplyAttrToCell(attr, cell);
|
|
}
|
|
}
|
|
else if (colPos < 1)
|
|
{
|
|
// Style is to be applied to entire row.
|
|
if (row != null)
|
|
{
|
|
for (int cellColIdx = row.FirstCellNum; cellColIdx < row.LastCellNum; cellColIdx++)
|
|
{
|
|
ICell cell = row.GetCell(cellColIdx, MissingCellPolicy.RETURN_NULL_AND_BLANK);
|
|
if (cell == null) continue;
|
|
ApplyAttrToCell(attr, cell);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Apply style to cell.
|
|
ICell cell = GetCell(colPos, rowPos, true);
|
|
ApplyAttrToCell(attr, cell);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc) { HandleException(SysUtil.Fn, exc); }
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private ICellStyle CloneCellStyle(ICellStyle cellStyle)
|
|
{
|
|
ICellStyle cellStyleNew = workbook.CreateCellStyle();
|
|
cellStyleNew.CloneStyleFrom(cellStyle);
|
|
return cellStyleNew;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private void ApplyAttrToCell(SaMsExcelStyleAttr attr, ICell cell)
|
|
{
|
|
if (cell == null) return;
|
|
Dictionary<String, Object> styleProperties = GetStyleProperties(attr);
|
|
if (attr.FontAttr.IsSpecified())
|
|
PopulateFontStyleProperties(styleProperties, attr, cell.CellStyle.GetFont(workbook));
|
|
if (styleProperties.IsEmpty()) return;
|
|
CellUtil.SetCellStyleProperties(cell, styleProperties);
|
|
}
|
|
|
|
private void ApplyAttrToCellStyle(SaMsExcelStyleAttr attr, ICellStyle cellStyle)
|
|
{
|
|
Dictionary<String, Object> styleProperties = GetStyleProperties(attr);
|
|
if (attr.FontAttr.IsSpecified())
|
|
PopulateFontStyleProperties(styleProperties, attr, cellStyle.GetFont(workbook));
|
|
ApplyStylingProperties(cellStyle, styleProperties);
|
|
}
|
|
|
|
private Dictionary<String, Object> GetStyleProperties(SaMsExcelStyleAttr attr)
|
|
{
|
|
// Style properties to change via CellUtil (when cell specified).
|
|
Dictionary<String, Object> styleProperties = new Dictionary<String, Object>();
|
|
|
|
if (attr.MergeCells ?? false)
|
|
{
|
|
// Merge cells.
|
|
}
|
|
|
|
if (!StringUtil.IsBlank(attr.DataFormat))
|
|
{
|
|
// Data format.
|
|
IDataFormat dataFormat = workbook.CreateDataFormat();
|
|
short dataFormatIdx = dataFormat.GetFormat(attr.DataFormat);
|
|
if (dataFormatIdx >= 0)
|
|
styleProperties.Add(CellUtil.DATA_FORMAT, dataFormatIdx);
|
|
}
|
|
|
|
// Alignment.
|
|
if (attr.HorizontalAlignment != null)
|
|
{
|
|
styleProperties.Add(CellUtil.ALIGNMENT, GetPoiHorizontalAlignment((XlHAlign)attr.HorizontalAlignment));
|
|
}
|
|
|
|
// Vertical alignment.
|
|
if (attr.VerticalAlignment != null)
|
|
{
|
|
styleProperties.Add(CellUtil.VERTICAL_ALIGNMENT, GetPoiVerticalAlignment((XlVAlign)attr.VerticalAlignment));
|
|
}
|
|
|
|
// Indentation.
|
|
if (attr.IndentLevel != null)
|
|
{
|
|
styleProperties.Add(CellUtil.INDENTION, (short)attr.IndentLevel);
|
|
}
|
|
|
|
// Wrap text.
|
|
if (attr.WrapText ?? false)
|
|
{
|
|
styleProperties.Add(CellUtil.WRAP_TEXT, (bool)attr.WrapText);
|
|
}
|
|
|
|
// Interior colour and pattern.
|
|
if (attr.ForegroundColourIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
styleProperties.Add(CellUtil.FILL_FOREGROUND_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.ForegroundColourIndex, IndexedColors.White.Index));
|
|
styleProperties.Add(CellUtil.FILL_PATTERN, FillPattern.SolidForeground);
|
|
}
|
|
else if (attr.ForegroundColourRGB != null)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? interiorColourIndex = GetCustomerColourIndex((int)attr.ForegroundColourRGB);
|
|
if (interiorColourIndex != null)
|
|
{
|
|
styleProperties.Add(CellUtil.FILL_PATTERN, FillPattern.SolidForeground);
|
|
styleProperties.Add(CellUtil.FILL_FOREGROUND_COLOR, interiorColourIndex);
|
|
}
|
|
}
|
|
if (attr.InteriorPattern != SaXlPattern.NotSpecified)
|
|
{
|
|
styleProperties.Add(CellUtil.FILL_PATTERN, (FillPattern)attr.InteriorPattern);
|
|
}
|
|
if (attr.BackgroundColourIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
styleProperties.Add(CellUtil.FILL_BACKGROUND_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.BackgroundColourIndex, IndexedColors.White.Index));
|
|
}
|
|
else if (attr.BackgroundPatternColour != null)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? interiorPatternColourIndex = GetCustomerColourIndex((int)attr.BackgroundPatternColour);
|
|
if (interiorPatternColourIndex != null)
|
|
styleProperties.Add(CellUtil.FILL_BACKGROUND_COLOR, (short)interiorPatternColourIndex);
|
|
}
|
|
|
|
// Borders.
|
|
if (attr.BorderTop.IsSpecified)
|
|
{
|
|
if (attr.BorderTop.Weight != SaXlBorderWeight.NotSpecified || attr.BorderTop.LineStyle != SaXlLineStyle.NotSpecified)
|
|
styleProperties.Add(CellUtil.BORDER_TOP, GetBorderStyle(attr.BorderTop));
|
|
if (attr.BorderTop.Color != null)
|
|
styleProperties.Add(CellUtil.TOP_BORDER_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.BorderTop.Color.Value, IndexedColors.Black.Index));
|
|
else if (attr.BorderTop.ColorIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.BorderTop.ColorIndex);
|
|
if (colourIndex != null)
|
|
styleProperties.Add(CellUtil.TOP_BORDER_COLOR, (short)colourIndex);
|
|
}
|
|
}
|
|
if (attr.BorderBottom.IsSpecified)
|
|
{
|
|
if (attr.BorderBottom.Weight != SaXlBorderWeight.NotSpecified || attr.BorderBottom.LineStyle != SaXlLineStyle.NotSpecified)
|
|
styleProperties.Add(CellUtil.BORDER_BOTTOM, GetBorderStyle(attr.BorderBottom));
|
|
if (attr.BorderBottom.Color != null)
|
|
styleProperties.Add(CellUtil.BOTTOM_BORDER_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.BorderBottom.Color, IndexedColors.Black.Index));
|
|
else if (attr.BorderBottom.ColorIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.BorderBottom.ColorIndex);
|
|
if (colourIndex != null)
|
|
styleProperties.Add(CellUtil.BOTTOM_BORDER_COLOR, (short)colourIndex);
|
|
}
|
|
}
|
|
if (attr.BorderLeft.IsSpecified)
|
|
{
|
|
if (attr.BorderLeft.Weight != SaXlBorderWeight.NotSpecified || attr.BorderLeft.LineStyle != SaXlLineStyle.NotSpecified)
|
|
styleProperties.Add(CellUtil.BORDER_LEFT, GetBorderStyle(attr.BorderLeft));
|
|
if (attr.BorderLeft.Color != null)
|
|
styleProperties.Add(CellUtil.LEFT_BORDER_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.BorderLeft.Color, IndexedColors.Black.Index));
|
|
else if (attr.BorderLeft.ColorIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.BorderLeft.ColorIndex);
|
|
if (colourIndex != null)
|
|
styleProperties.Add(CellUtil.LEFT_BORDER_COLOR, (short)colourIndex);
|
|
}
|
|
}
|
|
if (attr.BorderRight.IsSpecified)
|
|
{
|
|
if (attr.BorderRight.Weight != SaXlBorderWeight.NotSpecified || attr.BorderRight.LineStyle != SaXlLineStyle.NotSpecified)
|
|
styleProperties.Add(CellUtil.BORDER_RIGHT, GetBorderStyle(attr.BorderRight));
|
|
if (attr.BorderRight.Color != null)
|
|
styleProperties.Add(CellUtil.RIGHT_BORDER_COLOR, GetPoiColourIndex((SaXlColourIndex)attr.BorderRight.Color, IndexedColors.Black.Index));
|
|
else if (attr.BorderRight.ColorIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.BorderRight.ColorIndex);
|
|
if (colourIndex != null)
|
|
styleProperties.Add(CellUtil.RIGHT_BORDER_COLOR, (short)colourIndex);
|
|
}
|
|
}
|
|
return styleProperties;
|
|
}
|
|
|
|
private HorizontalAlignment GetPoiHorizontalAlignment(XlHAlign hAlign)
|
|
{
|
|
switch (hAlign)
|
|
{
|
|
case XlHAlign.xlHAlignGeneral: return HorizontalAlignment.General;
|
|
case XlHAlign.xlHAlignLeft: return HorizontalAlignment.Left;
|
|
case XlHAlign.xlHAlignCenter: return HorizontalAlignment.Center;
|
|
case XlHAlign.xlHAlignRight: return HorizontalAlignment.Right;
|
|
case XlHAlign.xlHAlignJustify: return HorizontalAlignment.Justify;
|
|
case XlHAlign.xlHAlignCenterAcrossSelection: return HorizontalAlignment.CenterSelection;
|
|
case XlHAlign.xlHAlignFill: return HorizontalAlignment.Fill;
|
|
case XlHAlign.xlHAlignDistributed: return HorizontalAlignment.Distributed;
|
|
}
|
|
return HorizontalAlignment.General;
|
|
}
|
|
|
|
private VerticalAlignment GetPoiVerticalAlignment(XlVAlign vAlign)
|
|
{
|
|
switch (vAlign)
|
|
{
|
|
case XlVAlign.xlVAlignTop: return VerticalAlignment.Top;
|
|
case XlVAlign.xlVAlignJustify: return VerticalAlignment.Justify;
|
|
case XlVAlign.xlVAlignDistributed: return VerticalAlignment.Distributed;
|
|
case XlVAlign.xlVAlignCenter: return VerticalAlignment.Center;
|
|
case XlVAlign.xlVAlignBottom: return VerticalAlignment.Bottom;
|
|
}
|
|
return VerticalAlignment.None;
|
|
}
|
|
|
|
private void PopulateFontStyleProperties(Dictionary<String, Object> styleProperties, SaMsExcelStyleAttr attr, IFont fontBase)
|
|
{
|
|
int fontIndex = GetFontIndex(attr, fontBase);
|
|
if (fontIndex >= 0)
|
|
styleProperties.Add(CellUtil.FONT, (short)fontIndex);
|
|
}
|
|
|
|
private short GetFontIndex(SaMsExcelStyleAttr attr, IFont fontBase)
|
|
{
|
|
if (!attr.FontAttr.IsSpecified()) return -1;
|
|
|
|
// Base font attributes.
|
|
bool bold = fontBase.IsBold;
|
|
short color = fontBase.Color;
|
|
double heightInPoints = fontBase.FontHeightInPoints;
|
|
String name = fontBase.FontName;
|
|
bool italic = fontBase.IsItalic;
|
|
bool strikeout = fontBase.IsStrikeout;
|
|
FontSuperScript typeOffset = fontBase.TypeOffset;
|
|
FontUnderlineType underline = fontBase.Underline;
|
|
|
|
if (attr.FontAttr.Bold ?? false)
|
|
bold = true;
|
|
if (attr.FontAttr.ColourIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
color = GetPoiColourIndex((SaXlColourIndex)attr.FontAttr.ColourIndex, IndexedColors.Black.Index);
|
|
}
|
|
if (attr.FontAttr.ColourRGB != null)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.FontAttr.ColourRGB);
|
|
if (colourIndex != null)
|
|
color = (short)attr.FontAttr.ColourRGB;
|
|
}
|
|
if (attr.FontAttr.HeightInPoints != null && attr.FontAttr.HeightInPoints >= FontHeightInPointsMin && attr.FontAttr.HeightInPoints <= FontHeightInPointsMax)
|
|
heightInPoints = (double)attr.FontAttr.HeightInPoints;
|
|
if (!StringUtil.IsBlank(attr.FontAttr.Name))
|
|
name = attr.FontAttr.Name;
|
|
if (attr.FontAttr.Strikethrough ?? false)
|
|
strikeout = true;
|
|
if (attr.FontAttr.Superscript ?? false)
|
|
typeOffset = FontSuperScript.Super;
|
|
if (attr.FontAttr.Subscript ?? false)
|
|
typeOffset = FontSuperScript.Sub;
|
|
if (attr.FontAttr.Outline ?? false)
|
|
{
|
|
//font.OutlineFont = (short)attr.FontAttr.OutlineFont;
|
|
}
|
|
if (attr.FontAttr.Shadow ?? false)
|
|
{
|
|
//font.Shadow = true;
|
|
}
|
|
if (attr.FontAttr.Underline != null)
|
|
underline = (FontUnderlineType)attr.FontAttr.Underline;
|
|
|
|
// Check if equivalent font is already available.
|
|
IFont fontTarget = workbook.FindFont(bold, color, (short)(heightInPoints * 20), name, italic, strikeout, typeOffset, underline);
|
|
if (fontTarget == null)
|
|
{
|
|
// Create required font.
|
|
fontTarget = workbook.CreateFont();
|
|
fontTarget.IsBold = bold;
|
|
fontTarget.Color = color;
|
|
fontTarget.FontHeightInPoints = heightInPoints;
|
|
fontTarget.FontName = name;
|
|
fontTarget.IsItalic = italic;
|
|
fontTarget.IsStrikeout = strikeout;
|
|
fontTarget.TypeOffset = typeOffset;
|
|
fontTarget.Underline = underline;
|
|
}
|
|
if (fontTarget != null)
|
|
return fontTarget.Index;
|
|
SaLogger.Warn(SysUtil.Fn + " Failed to identify required font.");
|
|
return -1;
|
|
}
|
|
|
|
private void ApplyFontAttr(IFont font, SaMsExcelStyleAttr attr)
|
|
{
|
|
if (attr.FontAttr.Bold ?? false)
|
|
font.IsBold = true;
|
|
if (attr.FontAttr.ColourIndex != SaXlColourIndex.NotSpecified)
|
|
{
|
|
font.Color = GetPoiColourIndex(attr.FontAttr.ColourIndex, IndexedColors.Black.Index);
|
|
}
|
|
if (attr.FontAttr.ColourRGB != null)
|
|
{
|
|
// Convert RGB colour to palette index.
|
|
short? colourIndex = GetCustomerColourIndex((int)attr.FontAttr.ColourRGB);
|
|
if (colourIndex != null)
|
|
font.Color = (short)attr.FontAttr.ColourRGB;
|
|
}
|
|
if (attr.FontAttr.HeightInPoints != null && attr.FontAttr.HeightInPoints >= FontHeightInPointsMin && attr.FontAttr.HeightInPoints <= FontHeightInPointsMax)
|
|
font.FontHeightInPoints = (double)attr.FontAttr.HeightInPoints;
|
|
if (!StringUtil.IsBlank(attr.FontAttr.Name))
|
|
font.FontName = attr.FontAttr.Name;
|
|
if (attr.FontAttr.Strikethrough ?? false)
|
|
font.IsStrikeout = true;
|
|
if (attr.FontAttr.Superscript ?? false)
|
|
font.TypeOffset = FontSuperScript.Super;
|
|
if (attr.FontAttr.Subscript ?? false)
|
|
font.TypeOffset = FontSuperScript.Sub;
|
|
if (attr.FontAttr.Outline ?? false)
|
|
{
|
|
//font.OutlineFont = (short)attr.FontAttr.OutlineFont;
|
|
}
|
|
if (attr.FontAttr.Shadow ?? false)
|
|
{
|
|
//font.Shadow = true;
|
|
}
|
|
if (attr.FontAttr.Underline != null)
|
|
font.Underline = (FontUnderlineType)attr.FontAttr.Underline;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private short GetPoiColourIndex(SaXlColourIndex colourIndex, short defaultPoiColorIndex)
|
|
{
|
|
IndexedColors poiColor = IndexedColors.ValueOf(colourIndex.GetName());
|
|
if (poiColor != null) return poiColor.Index;
|
|
return defaultPoiColorIndex;
|
|
}
|
|
|
|
private short? GetCustomerColourIndex(int rgbColour)
|
|
{
|
|
if (workbook is HSSFWorkbook)
|
|
{
|
|
HSSFPalette palette = ((HSSFWorkbook)workbook).GetCustomPalette();
|
|
byte red = (byte)((rgbColour >> 0) & 0xff);
|
|
byte green = (byte)((rgbColour >> 8) & 0xff);
|
|
byte blue = (byte)((rgbColour >> 16) & 0xff);
|
|
// Get the color which most closely matches the color you want to use
|
|
return palette.FindSimilarColor(red, green, blue).Indexed;
|
|
}
|
|
else if (workbook is XSSFWorkbook)
|
|
{
|
|
StylesTable stylesTable = ((XSSFWorkbook)workbook).GetStylesSource();
|
|
byte red = (byte)((rgbColour >> 0) & 0xff);
|
|
byte green = (byte)((rgbColour >> 8) & 0xff);
|
|
byte blue = (byte)((rgbColour >> 16) & 0xff);
|
|
IIndexedColorMap colorMap = stylesTable.GetIndexedColors();
|
|
for (int styleIdx = 0; styleIdx < stylesTable.NumCellStyles; styleIdx++)
|
|
{
|
|
ICellStyle style = stylesTable.GetStyleAt(styleIdx);
|
|
if (RGBMatches(colorMap.GetRGB(style.FillForegroundColor), red, green, blue))
|
|
return style.FillForegroundColor;
|
|
if (RGBMatches(colorMap.GetRGB(style.FillForegroundColor), red, green, blue))
|
|
return style.FillForegroundColor;
|
|
// ToDo Other colours in style.
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private bool RGBMatches(byte[] rgb, byte red, byte green, byte blue)
|
|
{
|
|
if (rgb.Count() != 3) return false;
|
|
if (rgb[0] != red) return false;
|
|
if (rgb[1] != green) return false;
|
|
if (rgb[2] != blue) return false;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private void ApplyStylingProperties(ICellStyle cellStyle, Dictionary<String, object> styleProperties)
|
|
{
|
|
foreach (String propertyName in styleProperties.Keys)
|
|
{
|
|
object propertyValue = styleProperties[propertyName];
|
|
if (propertyValue == null)
|
|
{
|
|
SaLogger.Info(SysUtil.Fn + " Null value for style property '" + propertyName + "'");
|
|
continue;
|
|
}
|
|
switch (propertyName)
|
|
{
|
|
// Data format.
|
|
case CellUtil.DATA_FORMAT:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.DataFormat = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Horizontal alignment.
|
|
case CellUtil.ALIGNMENT:
|
|
if (propertyValue is HorizontalAlignment || propertyValue is short)
|
|
{
|
|
cellStyle.Alignment = (HorizontalAlignment)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Vertical alignment.
|
|
case CellUtil.VERTICAL_ALIGNMENT:
|
|
if (propertyValue is VerticalAlignment || propertyValue is short)
|
|
{
|
|
cellStyle.VerticalAlignment = (VerticalAlignment)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Indentation.
|
|
case CellUtil.INDENTION:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.Indention = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Wrap text.
|
|
case CellUtil.WRAP_TEXT:
|
|
if (propertyValue is bool)
|
|
{
|
|
cellStyle.WrapText = (bool)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Fill colours and pattern.
|
|
case CellUtil.FILL_FOREGROUND_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.FillForegroundColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.FILL_BACKGROUND_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.FillBackgroundColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.FILL_PATTERN:
|
|
if (propertyValue is FillPattern || propertyValue is short)
|
|
{
|
|
cellStyle.FillPattern = (FillPattern)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Hidden.
|
|
case CellUtil.HIDDEN:
|
|
if (propertyValue is bool)
|
|
{
|
|
cellStyle.IsHidden = (bool)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Locked.
|
|
case CellUtil.LOCKED:
|
|
if (propertyValue is bool)
|
|
{
|
|
cellStyle.IsLocked = (bool)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Rotation.
|
|
case CellUtil.ROTATION:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.Rotation = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Shrink to fit.
|
|
case CellUtil.SHRINK_TO_FIT:
|
|
if (propertyValue is bool)
|
|
{
|
|
cellStyle.ShrinkToFit = (bool)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Borders.
|
|
case CellUtil.BORDER_TOP:
|
|
if (propertyValue is BorderStyle || propertyValue is short)
|
|
{
|
|
cellStyle.BorderTop = (BorderStyle)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.TOP_BORDER_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.TopBorderColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.BORDER_BOTTOM:
|
|
if (propertyValue is BorderStyle || propertyValue is short)
|
|
{
|
|
cellStyle.BorderBottom = (BorderStyle)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.BOTTOM_BORDER_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.BottomBorderColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.BORDER_LEFT:
|
|
if (propertyValue is BorderStyle || propertyValue is short)
|
|
{
|
|
cellStyle.BorderLeft = (BorderStyle)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.LEFT_BORDER_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.LeftBorderColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.BORDER_RIGHT:
|
|
if (propertyValue is BorderStyle || propertyValue is short)
|
|
{
|
|
cellStyle.BorderRight = (BorderStyle)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.RIGHT_BORDER_COLOR:
|
|
if (propertyValue is short)
|
|
{
|
|
cellStyle.RightBorderColor = (short)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
case CellUtil.BORDER_DIAGONAL:
|
|
if (propertyValue is BorderDiagonal || propertyValue is short)
|
|
{
|
|
cellStyle.BorderDiagonal = (BorderDiagonal)propertyValue;
|
|
continue;
|
|
}
|
|
break;
|
|
// Font.
|
|
case CellUtil.FONT:
|
|
if (propertyValue is short)
|
|
{
|
|
IFont font = workbook.GetFontAt((short)propertyValue);
|
|
if (font != null)
|
|
cellStyle.SetFont(font);
|
|
continue;
|
|
}
|
|
if (propertyValue is IFont)
|
|
{
|
|
// Shouldn't get here.
|
|
cellStyle.SetFont((IFont)propertyValue);
|
|
continue;
|
|
}
|
|
break;
|
|
default:
|
|
SaLogger.Info(SysUtil.Fn + " Unrecognised style property '" + propertyName + "'");
|
|
continue;
|
|
}
|
|
// Only get here for a valid property with invalid value type.
|
|
SaLogger.Info(SysUtil.Fn + " Invalid value type for style property '" + propertyName + "': " + propertyValue.GetType().Name);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private BorderStyle GetBorderStyle(SaMsExcelBorderAttr borderAttr)
|
|
{
|
|
// POI Border style:
|
|
// None No border
|
|
// Thin Thin border
|
|
// Medium Medium border
|
|
// Dashed dash border
|
|
// Dotted dot border
|
|
// Thick Thick border
|
|
// Double double-line border
|
|
// Hair hair-line border
|
|
// MediumDashed Medium dashed border
|
|
// DashDot dash-dot border
|
|
// MediumDashDot medium dash-dot border
|
|
// DashDotDot dash-dot-dot border
|
|
// MediumDashDotDot medium dash-dot-dot border
|
|
// SlantedDashDot slanted dash-dot border
|
|
BorderStyle borderStyle = BorderStyle.None;
|
|
if (borderAttr.Weight != SaXlBorderWeight.NotSpecified)
|
|
{
|
|
if (borderAttr.Weight == SaXlBorderWeight.Hairline)
|
|
borderStyle = BorderStyle.Hair;
|
|
else if (borderAttr.Weight == SaXlBorderWeight.Thin)
|
|
borderStyle = BorderStyle.Thin;
|
|
else if (borderAttr.Weight == SaXlBorderWeight.Medium)
|
|
borderStyle = BorderStyle.Medium;
|
|
else if (borderAttr.Weight == SaXlBorderWeight.Thick)
|
|
borderStyle = BorderStyle.Thick;
|
|
}
|
|
if (borderAttr.LineStyle != SaXlLineStyle.NotSpecified)
|
|
{
|
|
if (borderAttr.LineStyle == SaXlLineStyle.None)
|
|
borderStyle = BorderStyle.None;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.Double)
|
|
borderStyle = BorderStyle.Double;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.Dot)
|
|
borderStyle = BorderStyle.Dotted;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.Dash)
|
|
borderStyle = borderAttr.Weight == SaXlBorderWeight.Medium || borderAttr.Weight == SaXlBorderWeight.Thick ? BorderStyle.MediumDashed : BorderStyle.Dashed;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.Continuous)
|
|
borderStyle = borderAttr.Weight == SaXlBorderWeight.Hairline ? BorderStyle.Hair : borderAttr.Weight == SaXlBorderWeight.Thin ? BorderStyle.Thin : borderAttr.Weight == SaXlBorderWeight.Medium ? BorderStyle.Medium : borderAttr.Weight == SaXlBorderWeight.Thick ? BorderStyle.Thick : BorderStyle.Thin;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.DashDot)
|
|
borderStyle = borderAttr.Weight == SaXlBorderWeight.Medium || borderAttr.Weight == SaXlBorderWeight.Thick ? BorderStyle.MediumDashDot : BorderStyle.DashDot;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.DashDotDot)
|
|
borderStyle = borderAttr.Weight == SaXlBorderWeight.Medium || borderAttr.Weight == SaXlBorderWeight.Thick ? BorderStyle.MediumDashDotDot : BorderStyle.DashDotDot;
|
|
else if (borderAttr.LineStyle == SaXlLineStyle.SlantDashDot)
|
|
borderStyle = BorderStyle.SlantedDashDot;
|
|
}
|
|
return borderStyle;
|
|
}
|
|
|
|
private void SetCellStyle(uint colPos, uint rowPos, ICellStyle cellStyle)
|
|
{
|
|
ICell cell = GetCell(colPos, rowPos);
|
|
SetCellStyle(cell, cellStyle);
|
|
}
|
|
|
|
private void SetCellStyle(ICell cell, ICellStyle cellStyle)
|
|
{
|
|
if (cell != null)
|
|
cell.CellStyle = cellStyle;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Add image to sheet.
|
|
public override bool InsertImage(SaMsExcelImage_Config imageConfig)
|
|
{
|
|
return SetErrorState(SysUtil.Fn + " " + Msg_NotSupported);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool FreezePanes(uint colPos, uint rowPos)
|
|
{
|
|
return SetErrorState(SysUtil.Fn + " " + Msg_NotSupported);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool AutoFitRows(SaMsExcelRange range)
|
|
{
|
|
try
|
|
{
|
|
for (uint rowPos = range.RowFromPos; rowPos > 0 && rowPos <= range.RowToPos; rowPos++)
|
|
{
|
|
IRow row = worksheet.GetRow((int)rowPos - 1);
|
|
if (row != null)
|
|
row.Height = -1;
|
|
}
|
|
return true;
|
|
}
|
|
catch (Exception exc) { SetErrorState(SysUtil.Fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool SelectRange(SaMsExcelRange range)
|
|
{
|
|
return SetErrorState(SysUtil.Fn + " " + Msg_NotSupported);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
|
|
//=======================================================================
|
|
}
|