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
Related
To create the Excel files (.XLSX) using C# ASPNET I have added the Open XML and Closed XML reference from nugget packages.
I can not understand why happen that when try delete files xlsx in folder.
"the file is being used by another process."
The process is w3wp.exe
I need restart IIS on the server for delete all files in the folder.
Any suggestion?
public static void MTemptyxlxs()
{
string AppLocation = "";
AppLocation = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
AppLocation = AppLocation.Replace("file:\\", "");
foreach (string file in Directory.GetFiles(AppLocation, "*.xlsx").Where(item => item.EndsWith(".xlsx")))
{
File.Delete(file);
}
}
public static void ExportDataSetToExcel(DataSet ds)
{
string AppLocation = "";
AppLocation = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
AppLocation = AppLocation.Replace("file:\\", "");
string date = DateTime.Now.ToShortDateString();
date = date.Replace("/", "_");
string filepath = AppLocation + "\\ExcelFiles\\" + "RECEIPTS_COMPARISON_" + date + ".xlsx";
using (XLWorkbook wb = new XLWorkbook())
{
for (int i = 0; i < ds.Tables.Count; i++)
{
wb.Worksheets.Add(ds.Tables[i], ds.Tables[i].TableName);
}
wb.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
wb.Style.Font.Bold = true;
wb.SaveAs(filepath);
}
}
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;
}
}
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");
}
}
}
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.
I am currently using EPPlus project in order to manipulate some .xlsx files. The basic idea is that I have to create a new file from a given template.
But when I create the new file from a template, all calculated columns in the tables are messed up.
The code I am using is the following:
static void Main(string[] args)
{
const string templatePath = "template_worksheet.xlsx"; // the path of the template
const string resultPath = "result.xlsx"; // the path of our result
using (var pck = new ExcelPackage(new FileInfo(resultPath), new FileInfo(templatePath))) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
For example for a .xlsx file (that have a table with 3 columns, the last one is just the sum of the others) the program creates a .xlsx file where the last column have the same value (which is correct only for the first row) in all rows.
The following images shows the result:
Now the questions are:
What is going on here ? Is my code wrong ?
How can I accomplish this task without that unexpected behavior ?
That definitely on to something there. I was able to reproduce it myself. It has to do with the Table you created. if you open your file and remove it using the "Convert To Range" option in the Table Tools tab the problem goes away.
I looked at the source code and it extracts the xml files at the zip level and didnt see any indication that it was actually messing with them - seemed to be a straight copy.
Very strange because if we create and save the xlsx file including a table from EPPlus the problem is not there. This works just fine:
[TestMethod]
public void Template_Copy_Test()
{
//http://stackoverflow.com/questions/28722945/epplus-with-a-template-is-not-working-as-expected
const string templatePath = "c:\\temp\\testtemplate.xlsx"; // the path of the template
const string resultPath = "c:\\temp\\result.xlsx"; // the path of our result
//Throw in some data
var dtdata = new DataTable("tblData");
dtdata.Columns.Add(new DataColumn("Col1", typeof(string)));
dtdata.Columns.Add(new DataColumn("Col2", typeof(int)));
dtdata.Columns.Add(new DataColumn("Col3", typeof(int)));
for (var i = 0; i < 20; i++)
{
var row = dtdata.NewRow();
row["Col1"] = "String Data " + i;
row["Col2"] = i * 10;
row["Col3"] = i * 100;
dtdata.Rows.Add(row);
}
var templateFile = new FileInfo(templatePath);
if (templateFile.Exists)
templateFile.Delete();
using (var pck = new ExcelPackage(templateFile))
{
var ws = pck.Workbook.Worksheets.Add("Data");
ws.Cells["A1"].LoadFromDataTable(dtdata, true);
for (var i = 2; i <= dtdata.Rows.Count + 1; i++)
ws.Cells[i, 4].Formula = String.Format("{0}*{1}", ExcelCellBase.GetAddress(i, 2), ExcelCellBase.GetAddress(i, 3));
ws.Tables.Add(ws.Cells[1, 1, dtdata.Rows.Count + 1, 4], "TestTable");
pck.Save();
}
using (var pck = new ExcelPackage(new FileInfo(resultPath), templateFile)) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
BUT.....
If we open testtemplate.xlsx, remove the table, save/close the file, reopen, and reinsert the exact same table the problem shows up when you run this:
[TestMethod]
public void Template_Copy_Test2()
{
//http://stackoverflow.com/questions/28722945/epplus-with-a-template-is-not-working-as-expected
const string templatePath = "c:\\temp\\testtemplate.xlsx"; // the path of the template
const string resultPath = "c:\\temp\\result.xlsx"; // the path of our result
var templateFile = new FileInfo(templatePath);
using (var pck = new ExcelPackage(new FileInfo(resultPath), templateFile)) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
It has to be something burried in their zip copy methods but I nothing jumped out at me.
But at least you can see about working around it.
Ernie
Try to use the following code. This code takes the formatting and other rules and add them as xml node to another file. Ernie described it really well here Importing excel file with all the conditional formatting rules to epplus The best part of the solution is that you can also import formatting along with your other rules. It should take you close to what you need.
//File with your rules, can be your template
var existingFile = new FileInfo(#"c:\temp\temp.xlsx");
//Other file where you want the rules
var existingFile2 = new FileInfo(#"c:\temp\temp2.xlsx");
using (var package = new ExcelPackage(existingFile))
using (var package2 = new ExcelPackage(existingFile2))
{
//Make sure there are document element for the source
var worksheet = package.Workbook.Worksheets.First();
var xdoc = worksheet.WorksheetXml;
if (xdoc.DocumentElement == null)
return;
//Make sure there are document element for the destination
var worksheet2 = package2.Workbook.Worksheets.First();
var xdoc2 = worksheet2.WorksheetXml;
if (xdoc2.DocumentElement == null)
return;
//get the extension list node 'extLst' from the ws with the formatting
var extensionlistnode = xdoc
.DocumentElement
.GetElementsByTagName("extLst")[0];
//Create the import node and append it to the end of the xml document
var newnode = xdoc2.ImportNode(extensionlistnode, true);
xdoc2.LastChild.AppendChild(newnode);
package2.Save();
}
}
Try this
var package = new ExcelPackage(excelFile)
var excelSheet = package.Workbook.Worksheets[1];
for (var i = 1; i < 5; i++){
excelWorkSheet.InsertRow(i, 1, 1); // Use value of i or whatever is suitable for you
}
package.Workbook.Calculate();
Inserting new row copies previous row format and its formula if last prm is set to 1