update existing workbook using epplus C# - c#

I am trying to add new worksheet into existing workbook, code runs fine without any error. But changes are not being updated to the excel file.
Here is my code
string path = "C:\\TestFileSave\\ABC.xlsx";
FileInfo filePath = new FileInfo(path);
if (File.Exists(path))
{
using(ExcelPackage p = new ExcelPackage())
{
using(stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
{
p.Load(stream);
ExcelWorksheet ws = p.Workbook.Worksheets.Add(wsName + wsNumber.ToString());
ws.Cells[1, 1].Value = wsName;
ws.Cells[1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells[1, 1].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(184, 204, 228));
ws.Cells[1, 1].Style.Font.Bold = true;
p.Save();
}
}
}

The stream object is not tied to the package. The only relationship is it copies its bytes in your call to Load afterwards they are separate.
You do not need to even use a stream - better to let the package handle it on its own like this:
var fileinfo = new FileInfo(path);
if (fileinfo.Exists)
{
using (ExcelPackage p = new ExcelPackage(fileinfo))
{
//using (stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
{
//p.Load(stream);
ExcelWorksheet ws = p.Workbook.Worksheets.Add(wsName + wsNumber.ToString());
ws.Cells[1, 1].Value = wsName;
ws.Cells[1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells[1, 1].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(184, 204, 228));
ws.Cells[1, 1].Style.Font.Bold = true;
p.Save();
}
}
}

Here I have shown to write data into exiting excel file by creating a new sheet in same file. To answer your question: try using last two lines File.WriteAllBytes instead of p.Save().
string strfilepath = "C:\\Users\\m\\Desktop\\Employeedata.xlsx";
using (ExcelPackage p = new ExcelPackage())
{
using (FileStream stream = new FileStream(strfilepath, FileMode.Open))
{
p.Load(stream);
//deleting worksheet if already present in excel file
var wk = p.Workbook.Worksheets.SingleOrDefault(x => x.Name == "Hola");
if (wk != null) { p.Workbook.Worksheets.Delete(wk); }
p.Workbook.Worksheets.Add("Hola");
p.Workbook.Worksheets.MoveToEnd("Hola");
ExcelWorksheet worksheet = p.Workbook.Worksheets[p.Workbook.Worksheets.Count];
worksheet.InsertRow(5, 2);
worksheet.Cells["A9"].LoadFromDataTable(dt1, true);
// Inserting values in the 5th row
worksheet.Cells["A5"].Value = "12010";
worksheet.Cells["B5"].Value = "Drill";
worksheet.Cells["C5"].Value = 20;
worksheet.Cells["D5"].Value = 8;
// Inserting values in the 6th row
worksheet.Cells["A6"].Value = "12011";
worksheet.Cells["B6"].Value = "Crowbar";
worksheet.Cells["C6"].Value = 7;
worksheet.Cells["D6"].Value = 23.48;
}
//p.Save() ;
Byte[] bin = p.GetAsByteArray();
File.WriteAllBytes(#"C:\Users\m\Desktop\Employeedata.xlsx", bin);
}

I originally got the error code "A disk error occurred during a write operation. (Exception from HRESULT: 0x8003001D (STG_E_WRITEFAULT)) " from using this, but later learned that it was because the existing Excel file that I wanted to modify wasn't fully MS-Excel format compliant. I created thee original excel file in Open office as an .xls file, but EPPlus was not able to read it. When I regenerated this original excel file in Online Excel, everything worked fine.

Related

How to append to an existing Excel file?

I am trying to append to an existing worksheet using the code below but it overwrites the existing data instead of appending.
string filePath = "c:\\CompareReport.xlsx";
FileInfo fi = new FileInfo(filePath);
using (var package = new ExcelPackage(fi)) {
var currentSheet = package.Workbook.Worksheets;
var sheet = currentSheet.First();
sheet.Row(sheet.Dimension.End.Row);
sheet.Cells.LoadFromCollection(myData, true);
package.SaveAs(fi);
}

how to close File Stream in C#

Please see this code.
string name = dt.Rows[0]["Name"].ToString();
byte[] documentBytes = (byte[])dt.Rows[0]["DocumentContent"];
int readBytes = 0;
//int index = 0;
readBytes = documentBytes.Length;
try
{
using (FileStream fs = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.Read))
{
fs.Write(documentBytes, 0, readBytes);
//System.Diagnostics.Process prc = new System.Diagnostics.Process();
//prc.StartInfo.FileName = fs.Name;
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Open(fs.Name);
Microsoft.Office.Interop.Excel._Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1]; // Explicit cast is not required here
// lastRow = worksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
app.Visible = true;
fs.Flush();
fs.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("You have clicked more than one time. File is already open.", "WorkFlow", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
I am opening an excel file using the file stream. Excel is showing up nicely. But I am not able to close file stream. It still comes with a small pop up that shows 'File Now available'. How to get rid of that? I can see fs.Close() and Flush() really not working here. Please help.
You're asking Excel to open the file while you still have the stream open. Given that you're just trying to write bytes to it, I'd just use:
// This will close the file handle after writing the data
File.WriteAllBytes(name, documentBytes);
// Then you're fine to get Excel to open it
var app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
var workbook = app.Workbooks.Open(name);

Open ExcelPackage Object with Excel application without saving it on local file path

I have a text file with some information and I convert it to ExcelPackage Object using EPPlus, now I want to know if there is a way to open this object with excel without saving it to a local file? if is not possible can I use a temp directory to save it into a file, and then open it?
If you are talking about a windows app, you could just use something like System.IO.Path.GetTempPath(). You can get more info from here:
How to get temporary folder for current user
So, something like this:
[TestMethod]
public void TempFolderTest()
{
var path = Path.Combine(Path.GetTempPath(), "temp.xlsx");
var tempfile = new FileInfo(path);
if (tempfile.Exists)
tempfile.Delete();
//Save the file
using (var pck = new ExcelPackage(tempfile))
{
var ws = pck.Workbook.Worksheets.Add("Demo");
ws.Cells[1, 2].Value = "Excel Test";
pck.Save();
}
//open the file
Process.Start(tempfile.FullName);
}
if you are talking web you shouldn't need to save it all, just send it via Response:
using (ExcelPackage pck = new ExcelPackage())
{
var ws = pck.Workbook.Worksheets.Add("Demo");
ws.Cells[1, 2].Value = "Excel Test";
var fileBytes = pck.GetAsByteArray();
Response.Clear();
Response.AppendHeader("Content-Length", fileBytes.Length.ToString());
Response.AppendHeader("Content-Disposition",
String.Format("attachment; filename=\"{0}\"; size={1}; creation-date={2}; modification-date={2}; read-date={2}"
, "temp.xlsx"
, fileBytes.Length
, DateTime.Now.ToString("R"))
);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.BinaryWrite(fileBytes);
Response.End();
}

How to Save Excel File in a specific Folder

I am exporting excel file from database using following method.But i have one problem when i am exporting excel file than it is automatically downloading to download folder and i don't want this to be happen,I want my excel file to be downloaded in my project folder
var formsection = from fs in db.FormSections
join form in Form on fs.FormId equals form.FormId
select fs;
XLWorkbook wb = new XLWorkbook();
string sheetName = "ARTICLE"; //Give name for export file.
var Fs = wb.Worksheets.Add("FORMSECTION");
Fs.Cell(2, 1).InsertTable(formsection.ToList());// assign list here.
HttpContext.Response.Clear();
HttpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Response.AddHeader("content-disposition", String.Format(#"attachment;filename={0}.xlsx", sheetName.Replace(" ", "_")));
var filePath = Path.Combine(Server.MapPath("~/Content"));
using (MemoryStream memoryStream = new MemoryStream())
{
wb.SaveAs(memoryStream);
memoryStream.WriteTo(HttpContext.Response.OutputStream);
memoryStream.Close();
}
HttpContext.Response.End();
Here is an example that converts a datatable to a .csv file and save the file to the folder of your project for me its store the file in Domestic folder as the path given by me.
private void test(DataTable dt1) {
string csv = string.Empty;
foreach (DataColumn column in dt1.Columns)
{
//Add the Header row for CSV file.
csv += column.ColumnName + ',';
}
//Add new line.
csv += "\r\n";
foreach (DataRow row in dt1.Rows)
{
foreach (DataColumn column in dt1.Columns)
{
//Add the Data rows.
csv += row[column.ColumnName].ToString().Replace(",", ";") +',';
}
//Add new line.
csv += "\r\n";
}
string datetime = Convert.ToString(DateTime.Today.ToString("dd-MM-yyyy")).Trim();
string filepath = "C:\\Users\\Prateek\\Desktop\\MMR New 27-07 -\\Domestic\\";
string filename= #"BILLING_BOOK_NO" + "_4005" + "_"+datetime+".CSV";
string combinepath = filepath + filename;
System.IO.File.WriteAllText(combinepath,csv);
}`
You need to write the excel to your server first.
wb.SaveAs(filePath);
//encrypt the file
Encrypt(filePath);
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
memoryStream.Write(bytes, 0, (int)file.Length);
memoryStream.WriteTo(HttpContext.Response.OutputStream);
}
}
use code as below
public void ImportXLX()
{
string filePath = string.Format("{0}/{1}", Server.MapPath("~/Content/UploadedFolder"), #"C:\Users\Vipin\Desktop\Sheets\MyXL6.xlsx");
if (System.IO.File.Exists(filePath))
System.IO.File.Delete(filePath);
Request.Files["xlsFile"].SaveAs(filePath);
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
}

Problems with releasing an object and closing a spreadsheet?

I am using EPPlus to open a spreadsheet and then populate it with pictures and information.
When i try to delete a folder containing all the pictures i used to populate my spreadsheet i get the error that this file is in use with another application. What would be the correct way to release the objects used and close the spreadsheet?
using (var package = new ExcelPackage(existingFile))
{
ExcelWorkbook workBook = package.Workbook;
if (workBook != null)
{
if (workBook.Worksheets.Count > 0)
{
int i = 0;
foreach(ExcelWorksheet worksheet in workBook.Worksheets)
{
xlWorkSeet1[i] = worksheet;
i = i + 1;
}
}
}
//More code ...
FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xls", FileMode.Create);
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0, byData.Length);
aFile.Close();
xlWorkSeet1 = null;
workBook = null;
}//End using
String P = Path.Combine(tempFolderPathAlt, "ExtractedFiles");
bool directoryExists = Directory.Exists(P);
if (directoryExists)
Directory.Delete(P, true); // deletes sub-directories
The error i get is when it is trying to delete a photo i added to my spreadsheet.
Try out following and please let me know whether this helps
int writeTimeout = 200;
using (var aFile = new FileStream(tempFolderPathAlt + saveas + ".xls", FileMode.Create))
{
aFile.WriteTimeout = writeTimeout;
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0, byData.Length);
xlWorkSeet1 = null;
workBook = null;
Thread.Sleep(writeTimeout);
}

Categories

Resources