Get Excel HyperLink Cell String - c#

I'm trying to get the hyperlink string from an Excel cell using the excel data reader library in C#, but retrieving the cell and calling the ToString method didn't work.
This is my code so far:
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read)){
using var reader = ExcelReaderFactory.CreateReader(stream);
var result = reader.AsDataSet();
DataTable table = result.Tables[0];
bool jumpCol = true; // Avoid first lane
foreach (DataRow row in table.Rows)
{
if (jumpCol)
{
jumpCol = false;
continue;
}
}
PlateImage = row[6].ToString(); //This returns 0
I just need the hyperlink string:
=HYPERLINK("thisString.jpg")
Any ideas? Any library that allows me to do this?

Install Free Spire.XLS from NuGet:
Install-Package FreeSpire.XLS
Next, you can read the hyperlinks from Excel with the following code:
using Spire.Xls;
using System;
namespace RetrieveHyperlink
{
class Program
{
static void Main(string[] args)
{
Workbook wb = new Workbook();
wb.LoadFromFile(#"C:\Users\Administrator\Desktop\Hyperlinks.xlsx");
Worksheet sheet = wb.Worksheets[0];
foreach (var item in sheet.HyperLinks)
{
string address = item.Address;
CellRange range = item.Range;
Console.WriteLine(string.Format("Cell[{0},{1}] contains URL: {2}", range.Row, range.Column, address));
}
}
}
}
Keep in mind that the free version has a limitation of 5 sheets and 200 rows per sheet for .xls file format.

Related

save excel file to csv format without opening in .net core 3.1

I have a situation where I need to download and save excel file(.xlsx) to .CSV format in .net core console application.
Since, Microsoft.Interop packages are not compatible with .Net core 3.1, what other approach I can use to save Excel file as .CSV?
Appreciate suggestions.
This is a combination of multiple existing answers on SO.
First is from here
Convert the xlsx to a DataTable using ClosedXML
using ClosedXML.Excel;
...
public static DataTable GetDataFromExcel(string path, dynamic worksheet)
{
//Save the uploaded Excel file.
DataTable dt = new DataTable();
//Open the Excel file using ClosedXML.
using (XLWorkbook workBook = new XLWorkbook(path))
{
//Read the first Sheet from Excel file.
IXLWorksheet workSheet = workBook.Worksheet(worksheet);
//Create a new DataTable.
//Loop through the Worksheet rows.
bool firstRow = true;
foreach (IXLRow row in workSheet.Rows())
{
//Use the first row to add columns to DataTable.
if (firstRow)
{
foreach (IXLCell cell in row.Cells())
{
if (!string.IsNullOrEmpty(cell.Value.ToString()))
{
dt.Columns.Add(cell.Value.ToString());
}
else
{
break;
}
}
firstRow = false;
}
else
{
int i = 0;
DataRow toInsert = dt.NewRow();
foreach (IXLCell cell in row.Cells(1, dt.Columns.Count))
{
try
{
toInsert[i] = cell.Value.ToString();
}
catch (Exception ex)
{
//Handle this, or don't.
}
i++;
}
dt.Rows.Add(toInsert);
}
}
return dt;
}
If you need to do any data transformations, do it while the data is in a DataTable.
Then use CSVHelper to export as a CSV (SO answer I found had a solution that didn't use the Culture Info which was added as a requirement to the Library a few updates ago):
using CSVHelper;
using System.Globilization;
....
public static void SaveCSV(DataTable records)
{
string newFile = #"C:\somePath.csv";
using (StreamWriter writer = new StreamWriter(newFile))
{
using (CsvWriter csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
//add headers
foreach (DataColumn dc in records.Columns)
{
csv.WriteField(dc.ColumnName);
}
csv.NextRecord();
foreach(DataRow dr in records.Rows)
{
for (int i = 0; i< records.Columns.Count; i++)
{
csv.WriteField(dr[i]);
}
csv.NextRecord();
}
}
}
}

EPPlus: How can I replace all formulas with static values? [duplicate]

I am using Epplus to copy a worksheet from a wokbook and paste it in another workbook.I can able to copy the worksheet sucesssfully,by using the below code.
ExcelPackage masterPackage = new ExcelPackage(new FileInfo(#"C:\\Users\\350154\\Desktop\\vb workouts\\testsample.xlsx"));
ExcelPackage pckg = new ExcelPackage(new FileInfo("C:\\Users\\350154\\Desktop\\vb workouts\\as.xlsx"));
string workSheetName = pckg.Workbook.Worksheets[1].Name;
ExcelWorksheet pck = pckg.Workbook.Worksheets[1];
pck.ConditionalFormatting.RemoveAll();
masterPackage.Workbook.Worksheets.Add(workSheetName, pck);
The code copies the sheet sucessfully.But the copied sheet has formulas in their cells.So Values not copying in a new excel pls help me to solve this.
If you're just looking to copy the values from one spreadsheet into a new sheet in another, try this:
public static void CopySheetValues(string sourcePath, string sheetName, string destPath)
{
using (var src = new ExcelPackage(new FileInfo(sourcePath)))
using (var dest = new ExcelPackage(new FileInfo(destPath)))
{
var wsSrc = src.Workbook.Worksheets[sheetName];
var wsDest = dest.Workbook.Worksheets[wsSrc.Name] ?? dest.Workbook.Worksheets.Add(wsSrc.Name);
for (var r = 1; r <= wsSrc.Dimension.Rows; r++)
{
for (var c = 1; c <= wsSrc.Dimension.Columns; c++)
{
var cellSrc = wsSrc.Cells[r, c];
var cellDest = wsDest.Cells[r, c];
// Copy value
cellDest.Value = cellSrc.Value;
// Copy cell properties
cellDest.Style.Numberformat = cellSrc.Style.Numberformat;
cellDest.Style.Font.Bold = cellSrc.Style.Font.Bold;
// TODO... Add any additional properties that you may want to copy over
}
}
dest.Save();
}
}
UPDATE: Sample code updated to show how formatting can also be copied from the source to the destination worksheet
Thanks #Pete. But I found a way to copy an entire worksheet to another workbook while I was looking for a different issue. https://github.com/JanKallman/EPPlus/issues/94
You change the below line to add the worksheet to the workbook.
var wsDest = m_GeneratedHeader.Workbook.Worksheets[wsSrc.Name] ?? m_GeneratedHeader.Workbook.Worksheets.Add(wsSrc.Name, wsSrc);
No need to use the two 'for' loops to iterate through rows and columns to copy each property. Adding the worksheet will copy cell style, font style, merge cells, etc... Worked for me.
Note that this was introduced after EPPlus 4.5.0.1

Read Excel worksheet into DataTable using ClosedXML

I would like to read the contents of an Excel worksheet into a C# DataTable. The Excel worksheet could have a variable numbers of columns and rows. The first row in the Excel worksheet will always contain the column names but other rows may be blank.
All of the suggestions I have seen here in SO all assume the presence of Microsoft.ACE.OLEDB. I do not have this library installed on my system as when I try some of these solutions I get this error.
Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
Strange considering I have Office 2016 installed.
For this reason I was hoping to use the ClosedXML library via Nuget but I do not see any examples in their wiki of reading an Excel worksheet to a DataTable in C#.
This is example is not mine. I cannot remember where I got it from as it was in my archives. However, this works for me. The only issue I ran into was with blank cells. According to a dicussion on the ClosedXML GitHUb wiki page it has something to do with Excel not tracking empty cells that are not bounded by data. I found that if I added data to the cells and then removed the same data the process worked.
public static DataTable ImportExceltoDatatable(string filePath, string sheetName)
{
// Open the Excel file using ClosedXML.
// Keep in mind the Excel file cannot be open when trying to read it
using (XLWorkbook workBook = new XLWorkbook(filePath))
{
//Read the first Sheet from Excel file.
IXLWorksheet workSheet = workBook.Worksheet(1);
//Create a new DataTable.
DataTable dt = new DataTable();
//Loop through the Worksheet rows.
bool firstRow = true;
foreach (IXLRow row in workSheet.Rows())
{
//Use the first row to add columns to DataTable.
if (firstRow)
{
foreach (IXLCell cell in row.Cells())
{
dt.Columns.Add(cell.Value.ToString());
}
firstRow = false;
}
else
{
//Add rows to DataTable.
dt.Rows.Add();
int i = 0;
foreach (IXLCell cell in row.Cells(row.FirstCellUsed().Address.ColumnNumber, row.LastCellUsed().Address.ColumnNumber))
{
dt.Rows[dt.Rows.Count - 1][i] = cell.Value.ToString();
i++;
}
}
}
return dt;
}
}
Need to add
using System.Data;
using ClosedXML.Excel;
As well as the ClosedXML nuget package
For other datetime data type... this could be helpful... reference
if (cell.Address.ColumnLetter=="J") // Column with date datatype
{
DateTime dtime = DateTime.FromOADate(double.Parse(cell.Value.ToString()));
dt.Rows[dt.Rows.Count - 1][i] = dtime;
}
else
{
dt.Rows[dt.Rows.Count - 1][i] = cell.Value.ToString();
}
With this code you can read the contents of an excel sheet. You can specify the name of the sheet or the number, a dataSet will be returned with the contents of the sheet.
public static DataTable GetDataFromExcel(string path, dynamic worksheet)
{
//Save the uploaded Excel file.
DataTable dt = new DataTable();
//Open the Excel file using ClosedXML.
using (XLWorkbook workBook = new XLWorkbook(path))
{
//Read the first Sheet from Excel file.
IXLWorksheet workSheet = workBook.Worksheet(worksheet);
//Create a new DataTable.
//Loop through the Worksheet rows.
bool firstRow = true;
foreach (IXLRow row in workSheet.Rows())
{
//Use the first row to add columns to DataTable.
if (firstRow)
{
foreach (IXLCell cell in row.Cells())
{
if (!string.IsNullOrEmpty(cell.Value.ToString()))
{
dt.Columns.Add(cell.Value.ToString());
}
else
{
break;
}
}
firstRow = false;
}
else
{
int i = 0;
DataRow toInsert = dt.NewRow();
foreach (IXLCell cell in row.Cells(1, dt.Columns.Count))
{
try
{
toInsert[i] = cell.Value.ToString();
}
catch (Exception ex)
{
}
i++;
}
dt.Rows.Add(toInsert);
}
}
return dt;
}

Does NPOI have support to .xlsx format?

Will NPOI DLL recognize .xlsx file?
Currently I'm using NPOI 1.2.5 version DLL for Microsoft Excel 97-2003, but I need to access Excel sheets of extension .xlsx also.
Will NPOI support the above?
Code snippet:
static void Main(string[] args) {
XSSFWorkbook xssfwb;
using(FileStream file=new FileStream(
#"C:\Users\347702\Desktop\Hello.xlsx",
FileMode.Open, FileAccess.Read)) {
xssfwb=new XSSFWorkbook(file);
}
ISheet sheet=xssfwb.GetSheet("sheet1");
sheet.GetRow(1048576);
Console.WriteLine(sheet.GetRow(1048576).GetCell(0).StringCellValue);
}
You can read Excel files in .xls and .xlsx extensions with NPOI, you only need to add the next in the using section
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
The main thing is at the time you open the file, you have to distinguish between the extensions so you use the appropiate componente, and use an ISheet interface so you can reference the sheet independently of the file extension
//We get the file extension
fileExt = Path.GetExtension(fileName);
//Declare the sheet interface
ISheet sheet;
//Get the Excel file according to the extension
if (fileExt.ToLower() == ".xls")
{
//Use the NPOI Excel xls object
HSSFWorkbook hssfwb;
using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
hssfwb = new HSSFWorkbook(file);
}
//Assign the sheet
sheet = hssfwb.GetSheet(sheetName);
}
else //.xlsx extension
{
//Use the NPOI Excel xlsx object
XSSFWorkbook hssfwb;
using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
hssfwb = new XSSFWorkbook(file);
}
//Assign the sheet
sheet = hssfwb.GetSheet(sheetName);
}
Once you have the excel object you only need to read it (in NPOI rows and columns are zero based)
//Loop through the rows until we find an empty one
for (int row = 0; row <= sheet.LastRowNum; row++)
{
//Get the cell value
string cellValue = sheet.GetRow(row).GetCell(0).ToString().Trim(); //In the method GetCell you specify the column number you want to read, in the method GetRow you spacify the row
string cellValue2 = sheet.GetRow(row).GetCell(0).StringCellValue.Trim();
}
To read the cell valur you can use the .ToString() method or the StringCellValue property, but be careful the StringCellValue only works with string cells, with number and date cells it throws an exception.
Yes it does. NPOI 2.0 beta works. Here's a sample code to get you started:
class Program
{
static XSSFWorkbook hssfworkbook;
static DataSet dataSet1 = new DataSet();
static void Main(string[] args)
{
InitializeWorkbook(#"E:\Docs\HoursWidget_RTM.xlsx");
xlsxToDT();
DisplayData(dataSet1.Tables[0]);
Console.ReadLine();
}
static void InitializeWorkbook(string path)
{
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
hssfworkbook = new XSSFWorkbook(file);
}
}
static void xlsxToDT()
{
DataTable dt = new DataTable();
ISheet sheet = hssfworkbook.GetSheetAt(1);
IRow headerRow = sheet.GetRow(0);
IEnumerator rows = sheet.GetRowEnumerator();
int colCount = headerRow.LastCellNum;
int rowCount = sheet.LastRowNum;
for (int c = 0; c < colCount; c++)
{
dt.Columns.Add(headerRow.GetCell(c).ToString());
}
bool skipReadingHeaderRow = rows.MoveNext();
while (rows.MoveNext())
{
IRow row = (XSSFRow)rows.Current;
DataRow dr = dt.NewRow();
for (int i = 0; i < colCount; i++)
{
ICell cell = row.GetCell(i);
if (cell != null)
{
dr[i] = cell.ToString();
}
}
dt.Rows.Add(dr);
}
hssfworkbook = null;
sheet = null;
dataSet1.Tables.Add(dt);
}
static void DisplayData(DataTable table)
{
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
}
Console.WriteLine("-------------------------------------------");
}
}
}
May be the library didn't had this feature when the original answer(s) was provided, but now you can handle both xls and xlsx using the same code base without checking for file extensions.
The trick is to use WorkbookFactory class to transparently load both types of files. This will work as long as you are not using special features specific to either version.
using (FileStream fileStream = File.OpenRead(fullPathToExcelFile)) //fullPathToExcelFile can hold either a xls or xlsx, we don't care
{
IWorkbook workbook = WorkbookFactory.Create(fileStream);
ISheet worksheet = workbook.GetSheet("SampleSheet");
//Now read from the worksheet anyway you like
var value = worksheet.GetRow(1).GetCell(1);
}
NPOI 2.0 supports xlsx. You can download it from https://npoi.codeplex.com/releases/view/112932

How to read xslx with open XML SDK based on columns in each row in C#?

I am trying to read some .xslx files with the open xml sdk, but I'm really struggeling finding any good examples.
What I want to do is to read the entire XSLX file and loop through all of the rows and extract the cellvalue/celltext from the columns i specify.
Like the following:
GetCellText(rowId, ColumnLetter)
Is this possible?
Helpers:
private static string GetColumnName(string cellReference)
{
if (ColumnNameRegex.IsMatch(cellReference))
return ColumnNameRegex.Match(cellReference).Value;
throw new ArgumentOutOfRangeException(cellReference);
}
private static readonly Regex ColumnNameRegex = new Regex("[A-Za-z]+");
Code:
using (var document = SpreadsheetDocument.Open(stream, true))
{
var sheets = document.WorkbookPart.Workbook.Descendants<Sheet>();
foreach (Sheet sheet in sheets)
{
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);
Worksheet worksheet = worksheetPart.Worksheet;
var rows = worksheet.GetFirstChild<SheetData>().Elements<Row>();
foreach (var row in rows)
{
var cells = row.Elements<Cell>();
foreach (var cell in cells)
{
if(GetColumnName(cell.CellReference) == "A")
{
var str = cell.CellValue.Text;
// do whatewer you want
}
}
}
}
}
Your question is similar to this one
1) Open xml excel read cell value
You can get the row by ID and look-up the value by column name.
Hope that helps

Categories

Resources