Excel sheet in Microsoft excel interop. Save an image to a file - c#

I have installed EPPlus in my c# project and used it to locate the proper image in an Excel worksheet. I want to take the image now and save it as a PNG file.
FileInfo fi = new FileInfo(#"c:/folder/workbook.xlsx");
using (ExcelPackage excelPackage = new ExcelPackage(fi))
{
ExcelWorksheet ws = excelPackage.Workbook.Worksheets[0];
int imageCount = firstWorksheet.Drawings.Count;
for (int i = 0; i <= imageCount-1; i++)
{
if (firstWorksheet.Drawings[i].DrawingType.ToString().ToLower() == "picture")
{
save it to a file;
}
}
}
Here is what I did that works great. Of course this is a little abbreviated.
OfficeOpenXml.Drawing.ExcelDrawing image = firstWorksheet.Drawings[i];
OfficeOpenXml.Drawing.ExcelPicture p = (OfficeOpenXml.Drawing.ExcelPicture)image;
p.Image.Save(#"c:/autocell/becbec.png");
This works with embedded xml files / tables. I also pasted in jpegs and pngs and bitmaps and this code found and saved them just fine too.

You can give the export URL and then it will be shown in the excel file
Get Absolute URL function
private string GetAbsoluteUrl(string relativeUrl)
{
relativeUrl = relativeUrl.Replace("~/", string.Empty);
string[] splits = Request.Url.AbsoluteUri.Split('/');
if (splits.Length >= 2)
{
string url = splits[0] + "//";
for (int i = 2; i < splits.Length - 1; i++)
{
url += splits[i];
url += "/";
}
return url + relativeUrl;
}
return relativeUrl;
}
and save it like this
//Convert the Relative Url to Absolute Url and set it to Image control.
Image1.ImageUrl = this.GetAbsoluteUrl(Image1.ImageUrl);

FileInfo fi = new FileInfo(#"c:/folder/workbook.xlsx");
using (ExcelPackage excelPackage = new ExcelPackage(fi))
{
ExcelWorksheet ws = excelPackage.Workbook.Worksheets[0];
int imageCount = firstWorksheet.Drawings.Count;
for (int i = 0; i <= imageCount-1; i++)
{
if (firstWorksheet.Drawings[i].DrawingType.ToString().ToLower() ==
"picture")
{
// save it to a file;
OfficeOpenXml.Drawing.ExcelDrawing image = firstWorksheet.Drawings[i];
OfficeOpenXml.Drawing.ExcelPicture p =
(OfficeOpenXml.Drawing.ExcelPicture)image;
p.Image.Save(#"c:/autocell/becbec.png");
}
}
}

Related

How to convert a stream of Excel file to CSV?

I have a scenario, where i have a storage Blob which will have the Excel file, so in code level there is no Physical File path i have, so its Stream of file i will get the code. I need to Convert the same to CSV & push it back to the storage.
Tried below:-
Tried with Microsoft.Office.Interop.Excel
Excel.Application app = new Excel.Application();
app.DisplayAlerts = false;
// Open Excel Workbook for conversion.
Excel.Workbook excelWorkbook = app.Workbooks.Open(sourceFile);
// Save file as CSV file.
excelWorkbook.SaveAs(destinationFile, Excel.XlFileFormat.xlCSV);
Issue:- in the SourcePath , i don't have a physical location, and moreover there is no overload seems to take Byte or stream of file.
Tried https://github.com/youngcm2/CsvHelper.Excel , Demo code as follows.
using var reader = new CsvReader(new ExcelParser(FileContent, "JOB STATUSES", new CsvConfiguration(CultureInfo.CurrentCulture)));
Tried Below code even:-
using var parser = new ExcelParser(FileContent,CultureInfo.InvariantCulture); using var reader = new CsvReader(parser);
But here the ExcelParser is failing with Corrupterdfile with a valid CSV :(
Issue:- Here although there is a OverLoad to pass the Stream but is critical in my case. As there is no specific file format i have. It can be any Random EXCEL file. There no Specific class i can define.
I am missing something , can anyone help on this.
Scenario in my case:-
No Physical path to the File location . it's in Storage account, so Stream/Byte .
EXCEL File can be of any number of rows or columns no Fixed Model i can have but single sheet.
Use ExcelDataReader. It's available in NuGet.
using (var reader = ExcelReaderFactory.CreateReader(memoryStream, excelConfig))
{
var spreadsheet = reader.AsDataSet();
var table = spreadsheet.Tables[0];
var csv = table.ToCSV();
var bytes = Encoding.UTF8.GetBytes(csv);
return new StreamDataSource(bytes, table.TableName);
}
public static class TableExtension
{
public static string ToCSV(this DataTable dtDataTable)
{
var builder = new StringBuilder();
foreach (DataRow dr in dtDataTable.Rows)
{
for (int i = 0; i < dtDataTable.Columns.Count; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
string value = dr[i].ToString();
if (value.Contains(","))
{
value = string.Format("\"{0}\"", value);
builder.Append(value);
}
else
{
builder.Append(dr[i].ToString());
}
}
if (i < dtDataTable.Columns.Count - 1)
{
builder.Append(",");
}
}
builder.Append(Environment.NewLine);
}
var csv = builder.ToString();
return csv;
}
}

C# How to display only file name in dataGridView without full path in Winforms

I want to display only filename with extenstion .pdf, but this code shows me fullpath plus filename.pdf , but I want to display only filename.pdf
Hers is my code and thank you in advance.
string installedPath = Application.StartupPath + "pdfFiles\\" + PatId.ToString() + "\\" + Regnr;
String[] files = Directory.GetFiles(installedPath);
DataTable table = new DataTable();
table.Columns.Add("File name");
for (int i = 0; i < files.Length; i++)
{
FileInfo file = new FileInfo(files[i]);
table.Rows.Add(file);
}
dgvFiles.DataSource = table;
Maybe not the most professional solution, but a string.Split should do the work
for (int i = 0; i < files.Length; i++)
{
string[] temp = files[i].Split('\\');
string fileName = temp.Last();
FileInfo file = new FileInfo(fileName);
table.Rows.Add(file);
}

Loading tsv/csv file in excel sheet

This is my code.
public static string LoadPackage(DirectoryInfo outputDir, string name)
{
FileInfo newFile = new FileInfo(outputDir.FullName + #"\test.xlsx");
if (newFile.Exists)
{
newFile.Delete();
newFile = new FileInfo(outputDir.FullName + #"\test.xlsx");
}
var format = new ExcelTextFormat();
format.Delimiter = '\t';
format.SkipLinesBeginning = 1;
using (ExcelPackage package = new ExcelPackage())
{
LoadSheet(package, outputDir, name);
package.SaveAs(newFile);
}
return newFile.FullName;
}
And after that i call LoadSheet method in order to fill my excel file from tsv file.
public static void LoadSheet(ExcelPackage package, DirectoryInfo
outputDir, string name)
{
var ws = package.Workbook.Worksheets.Add("Content");
var format = new ExcelTextFormat();
format.Delimiter = '\t';
format.SkipLinesBeginning = 2;
format.SkipLinesEnd = 1;
var range = ws.Cells["A1"].LoadFromText(new
FileInfo(outputDir.FullName + "\\" + name), format,
TableStyles.Medium27, false);
}
And this is my code on button click event
if (BrowseFileUpload.HasFile)
{
var name = BrowseFileUpload.PostedFile.FileName;
InputTextBox.Text = name;
LoadData.LoadPackage(new
System.IO.DirectoryInfo("C:\\Users\\Nemanja\\Downloads"), name);
InfoLabel.Text = "Your data has been imported!!!";
InfoLabel.ForeColor = System.Drawing.Color.Blue;
InfoLabel.Font.Size = 20;
}
Everything is ok i create new excel file, sheet save it but it does not load data that i need it to load inside excel file. It's only empty file or i get a error the file is corrupted recover what you can.
Can someone figure out what can be a problem based on my explanation and this code. Thank you all good people.
I think that the problem may well be with the format of your source data. I've put together the following sample, based on your code, and it works fine.
var outFile = Path.ChangeExtension(filePath, ".xlsx");
using (var p = new ExcelPackage())
{
var fmt = new ExcelTextFormat();
fmt.Delimiter = '\t';
fmt.SkipLinesBeginning = 2;
fmt.SkipLinesEnd = 1;
fmt.EOL = ((char)10).ToString(); // THIS LINE FIXED THE PROBLEM (UNIX NEWLINE)
var ws = p.Workbook.Worksheets.Add("Imported Text");
ws.Cells[1, 1].LoadFromText(new FileInfo(filePath), fmt, TableStyles.Medium27, false);
p.SaveAs(new FileInfo(outFile));
}
Try running your data through this and see if you get the same issue or not.
UPDATED
The problem was a unix-style newline in the file - EPPlus expects a windows-style newline by default

Writing to Excel: Cannot access closed stream with EPPLUS

I've looked around, and for the most part I see examples for more complex problems than my own.
So, I've been suggested to use EPPLUS as opposed to EXCEL INTEROP because of the performance improvement. This is my first time using it, and the first time I've encountered memory streams, so I'm not exactly sure what's wrong here.
I'm trying to write to an Excel file and convert that excel file into a PDF. To do this, I installed through NUGET the following:
EPPLUS
EPPLUSExcel
This is my code:
if (DGVmain.RowCount > 0)
{
//Source
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
openFileDialog.ShowDialog();
lblSuccess.Text = openFileDialog.FileName;
lblPathings = Path.ChangeExtension(openFileDialog.FileName, null);
int count = DGVmain.RowCount;
int current = 0;
int ballast = 0;
For each row in a DataGridView, perform write to Excel, then convert to PDF.
foreach (DataGridViewRow row in DGVmain.Rows)
{
//Drag
if (lblSuccess.Text == null)
return;
string drags = Convert.ToString(row.Cells[0].Value);
string dragsy = Convert.ToString(row.Cells[1].Value);
Persona = drag;
generateID();
//Initialize the Excel File
try
{
Here is where I expect something to be wrong:
using (ExcelPackage p = new ExcelPackage())
{
using (FileStream stream = new FileStream(lblSuccess.Text, FileMode.Open))
{
ballast++;
lblItem.Text = "Item #" + ballast;
p.Load(stream);
ExcelWorkbook WB = p.Workbook;
if (WB != null)
{
if (WB.Worksheets.Count > 0)
{
ExcelWorksheet WS = WB.Worksheets.First();
WS.Cells[82, 12].Value = drag13;
WS.Cells[84, 12].Value = "";
WS.Cells[86, 12].Value = 0;
//========================== Form
WS.Cells[95, 5].Value = drag26;
WS.Cells[95, 15].Value = drag27;
WS.Cells[95, 24].Value = drag28;
WS.Cells[95, 33].Value = drag29;
//========================== Right-Seid
WS.Cells[14, 31].Value = drag27;
WS.Cells[17, 31].Value = drag27;
}
}
Byte[] bin = p.GetAsByteArray();
File.WriteAllBytes(lblPathings, bin);
}
p.Save();
}
}
catch (Exception ex)
{
MessageBox.Show("Write Excel: " + ex.Message);
}
Separate method to convert to PDF, utilizing EPPLUSEXCEL and SpireXLS.
finally
{
ConvertToPdf(lblSuccess.Text, finalformat);
}
}
}
The compiler is not throwing any errors except the one mentioned in the title.
You already saved the ExcelPackage here:
Byte[] bin = p.GetAsByteArray();
So when you later try and save it again here:
p.Save();
the ExcelPackage is already closed. I.e. remove the Save() call in your code and you're good.

Read Image file metadata

I want to upload an image file and then extract its basic information (author, dimensions, date created, modified, etc) and display it to the user. How can I do it.
A solution or reference to this problem in asp.net c# code would be helpful. But javascript or php would be ok as well.
Check this Link. You will get more Clearance about GetDetailsOf() and its File Properties based on the Win-OS version wise.
If you want to use C# code use below code to get Metadata's:
List<string> arrHeaders = new List<string>();
Shell shell = new ShellClass();
Folder rFolder = shell.NameSpace(_rootPath);
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
C# solution could be found here:
Link1
Link2
Bitmap image = new Bitmap(fileName);
PropertyItem[] propItems = image.PropertyItems;
foreach (PropertyItem item in propItems)
{
Console.WriteLine("iD: 0x" + item.Id.ToString("x"));
}
MSDN Reference
C# Tutorial Reference
try this...
private string doUpload()
{
// Initialize variables
string sSavePath;
sSavePath = "images/";
// Check file size (mustn’t be 0)
HttpPostedFile myFile = FileUpload1.PostedFile;
int nFileLen = myFile.ContentLength;
if (nFileLen == 0)
{
//**************
//lblOutput.Text = "No file was uploaded.";
return null;
}
// Check file extension (must be JPG)
if (System.IO.Path.GetExtension(myFile.FileName).ToLower() != ".jpg")
{
//**************
//lblOutput.Text = "The file must have an extension of JPG";
return null;
}
// Read file into a data stream
byte[] myData = new Byte[nFileLen];
myFile.InputStream.Read(myData, 0, nFileLen);
// Make sure a duplicate file doesn’t exist. If it does, keep on appending an
// incremental numeric until it is unique
string sFilename = System.IO.Path.GetFileName(myFile.FileName);
int file_append = 0;
while (System.IO.File.Exists(Server.MapPath(sSavePath + sFilename)))
{
file_append++;
sFilename = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName)
+ file_append.ToString() + ".jpg";
}
// Save the stream to disk
System.IO.FileStream newFile
= new System.IO.FileStream(Server.MapPath(sSavePath + sFilename),
System.IO.FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
return sFilename;
}

Categories

Resources