kreta/Kreta.BusinessLogic/Classes/ExcelHelpers/OpenXmlExcelUtils.cs
2024-03-13 00:33:46 +01:00

308 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace Kreta.BusinessLogic.Classes.ExcelHelpers
{
public static class OpenXmlExcelUtils
{
#region Tulajdonságok
public const string ExcelVersion = "0.1";
const string VersionNumberReference = "ZZ1";
public static string GetExcelColumnName(int columnNumber)
{
int dividend = columnNumber + 1;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
#endregion
#region GetColumnNameIndex
public static int GetColumnNameIndex(string column)
{
int retVal = 0;
string col = column.ToUpper();
for (int iChar = col.Length - 1; iChar >= 0; iChar--)
{
char colPiece = col[iChar];
int colNum = colPiece - 64;
retVal += colNum * (int)Math.Pow(26, col.Length - (iChar + 1));
}
return retVal;
}
#endregion
#region GetColumnIndex
public static int GetColumnIndex(string reference)
{
int ci = 0;
reference = reference.ToUpper();
for (int ix = 0; ix < reference.Length && reference[ix] >= 'A'; ix++)
{
ci = (ci * 26) + ((int)reference[ix] - 64);
}
return ci;
}
#endregion
#region create cell in worksheet
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, returns it.
// Given a Worksheet and a cell name, verifies that the specified cell exists.
// If it does not exist, creates a new cell.
public static Cell CreateSpreadsheetCellIfNotExist(Worksheet worksheet, string cellName)
{
string columnName = GetColumnName(cellName);
uint rowIndex = GetRowIndex(cellName);
Cell cell = new Cell();
IEnumerable<Row> rows = worksheet.Descendants<Row>().Where(r => r.RowIndex.Value == rowIndex);
// If the Worksheet does not contain the specified row, create the specified row.
// Create the specified cell in that row, and insert the row into the Worksheet.
if (!rows.Any())
{
Row row = new Row() { RowIndex = new UInt32Value(rowIndex) };
cell = new Cell() { CellReference = new StringValue(cellName) };
row.Append(cell);
worksheet.Descendants<SheetData>().First().Append(row);
}
else
{
Row row = rows.First();
IEnumerable<Cell> cells = row.Elements<Cell>().Where(c => c.CellReference.Value == cellName);
// If the row does not contain the specified cell, create the specified cell.
if (!cells.Any())
{
cell = new Cell() { CellReference = new StringValue(cellName) };
row.Append(cell);
}
}
return cell;
}
#endregion
#region InsertSharedStringItem
// Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text
// and inserts it into the SharedStringTablePart. If the item already exists, returns its index.
public static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
int i = 0;
// Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
if (item.InnerText == text)
{
return i;
}
i++;
}
// The text does not exist in the part. Create the SharedStringItem and return its index.
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));
shareStringPart.SharedStringTable.Save();
return i;
}
#endregion
#region GetColumnName
// Given a cell name, parses the specified cell to get the column name.
public static string GetColumnName(string cellName)
{
// Create a regular expression to match the column name portion of the cell name.
Regex regex = new Regex("[A-Za-z]+");
Match match = regex.Match(cellName);
return match.Value;
}
#endregion
#region GetRowIndex
// Given a cell name, parses the specified cell to get the row index.
public static uint GetRowIndex(string cellName)
{
// Create a regular expression to match the row index portion the cell name.
Regex regex = new Regex(@"\d+");
Match match = regex.Match(cellName);
return uint.Parse(match.Value);
}
#endregion
#region GetCell
/// <summary>
/// Visszaadja oszlop nev es sor index alapjan az adott cellat.
/// </summary>
/// <param name="worksheet"></param>
/// <param name="columnName"></param>
/// <param name="rowIndex"></param>
/// <returns></returns>
public static Cell GetCell(Worksheet worksheet,
string columnName, uint rowIndex)
{
Row row = GetRow(worksheet, rowIndex);
if (row == null)
{
return null;
}
IEnumerable<Cell> cells = row.Elements<Cell>().Where(c => string.Compare
(c.CellReference.Value, columnName +
rowIndex, StringComparison.OrdinalIgnoreCase) == 0);
return !cells.Any() ? null : cells.First();
}
#endregion
#region GetCellValue
public static string GetCellValue(Worksheet worksheet, SharedStringTable table, string reference)
{
var cell = worksheet.Descendants<Cell>().Where(c => string.Compare(c.CellReference.Value, reference, StringComparison.OrdinalIgnoreCase) == 0).FirstOrDefault();
if (cell == null)
{
return null;
}
return cell.DataType == CellValues.SharedString ? table.ElementAt(int.Parse(cell.InnerText)).InnerText : cell.InnerText;
}
#endregion
#region GetRow
/// <summary>
/// Visszaadja a sor indexe alapjan az adott sor referenciajat.
/// </summary>
/// <param name="worksheet"></param>
/// <param name="rowIndex"></param>
/// <returns></returns>
public static Row GetRow(Worksheet worksheet, uint rowIndex)
{
IEnumerable<Row> myRows = worksheet.GetFirstChild<SheetData>().
Elements<Row>().Where(r => r.RowIndex == rowIndex);
return !myRows.Any() ? null : myRows.First();
}
#endregion
#region GetCellValue2
/// <summary>
/// Visszaadja a cella alapjan a hozza tartozo erteket a sharedstring tablabol.
/// </summary>
/// <param name="table"></param>
/// <param name="cell"></param>
/// <returns></returns>
public static string GetCellValue(SharedStringTable table, Cell cell)
{
int index = -1;
if (cell.CellValue == null)
{
return "";
}
if (cell.DataType != null && cell.DataType == CellValues.SharedString && int.TryParse(cell.CellValue.Text, out index))
{
return table.Elements<SharedStringItem>().ElementAt(index).InnerText;
}
return cell.CellValue.InnerText;
}
#endregion
#region SetColumns
/// <summary>
/// beallitja az oszlopokat, elso korben a bestfitet.
/// </summary>
public static void SetColumns(Worksheet sheet, int colindex, double maxcolcharacter, bool hidden)
{
// ha nem letezik hozza oszlopok tulajdonsag
Columns cols;
if (!sheet.Descendants<Columns>().Any())
{
cols = new Columns();
sheet.Append(cols);
}
else
{
cols = sheet.Descendants<Columns>().First();
}
// oszlop letrehozasa, ahol elrejtjuk a validacios listat
double maxcolwidth = Math.Truncate(((maxcolcharacter * 7 + 5) / 7 * 256) / 256) + 2;
var col = new Column
{
Min = new UInt32Value((uint)colindex),
Max = new UInt32Value((uint)colindex),
Width = new DoubleValue(maxcolwidth),
Hidden = new BooleanValue(hidden),
BestFit = new BooleanValue(true),
CustomWidth = new BooleanValue(true)
};
cols.Append(col);
}
#endregion
#region Excel columns count
public static int GetColumnCount(Worksheet sheet)
{
var row = sheet.Descendants<Row>().FirstOrDefault();
return row != null ? row.Descendants<Cell>().Count() : 0;
}
#endregion
#region SetVersion
public static void SetVersion(Worksheet sheet, string versionNumber)
{
// verzió
// uj cella
Cell newVersionCell = CreateSpreadsheetCellIfNotExist(sheet, VersionNumberReference);
// majd index alapjan referenciat adok ra
var version = !string.IsNullOrWhiteSpace(versionNumber) ? versionNumber : ExcelVersion;
newVersionCell.CellValue = new CellValue(version);
// ez bizony egy sharedstring tipus
newVersionCell.DataType = new EnumValue<CellValues>(CellValues.String);
SetColumns(sheet, GetColumnIndex(VersionNumberReference), 0, true);
}
#endregion
#region Checkversion
public static bool CheckVersion(Worksheet sheet, SharedStringTable table, string versionNumber)
{
var excelVersion = GetCellValue(sheet, table, VersionNumberReference);
return versionNumber.Equals(excelVersion);
}
#endregion
}
}