I have a method were I create an Excelsheet. When the file is created I need to open it and save it manually in Excel before I can read it with Excel Data Reader. If I open and save the exact same file without changeing anything I can read it like I wan't it to work. Does anyone know how I can:
a) Save it properly when creating the file (using EPPlus)?
or
b) Open the already created file and save it properly by using C# before I try to read it?
My create method:
public void CreateAnnuityExcelSheet(List<Calculation> cList, FormCollection form, int DTCyear)
{
string fileName = "test";
string path = #"C:\ExcelFiles\" + fileName + ".xlsx"; //Path for the file
FileInfo info = new FileInfo(path);
info.Directory.Create(); //If C:\ExcelFiles does not exist, create it
if (!info.Exists)
{
using (ExcelPackage package = new ExcelPackage(info))
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add(fileName);
//Filling the worksheet with values here...
package.SaveAs(info);
}
}
}
My read method:
[HttpPost]
public ActionResult ShowExcelFile(GetExcel model)
{
List<Calculation> cList = new List<Calculation>();
DataSet result = null;
var file = model.Files[0];
if (file != null && file.ContentLength > 0)
{
// .xlsx
IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(file.InputStream);
reader.IsFirstRowAsColumnNames = true;
result = reader.AsDataSet();
reader.Close();
var PV = Convert.ToDecimal(data.Table.Rows[1][6]); //Works fine if the file is opened and saved in Excel. Else null..
//Work with the dataset here. When the file is not opened and saved it gets null everywhere. Else it works fine
}
return View("ShowExcelFile", model);
}
I have also tried using WriteAllBytes instead of using package.SaveAs():
byte[] data = package.GetAsByteArray();
System.IO.File.WriteAllBytes(path, data);
This gets my the exact same result. I still need to open and save the file manually.
Related
I'm trying to make a change in the application code, because I've tried it anyway and I'm not having success. I have a reporting tab on my system, but it is only exporting XLS files and I need to switch to XLSX because the XLS is limited to 65,000 lines. I'll show a part of my controler when he's mounting the XLS. I can not show my Service method because it is VERY large and you would be kind of lost.
[CustomAuthorize(TipoFuncao.PRINT)]
public ActionResult Index(FiltroRptManifesto filtro)
{
byte[] result = null;
bool overflowMonth = false;
IWorkbook workbook = new XSSFWorkbook();
try
{
RptManifestoService rptManifestoService = new RptManifestoService(ModelState);
result = rptManifestoService.GeraExcel(Server.MapPath("~/Content/RptManifesto.xls"), filtro, ViewBag.Usuario);
if (ModelState.IsValid)
{
if (ValidateDate(ModelState["DtProtocoloIni"].Value, ModelState["DtProtocoloFin"].Value).Days > 540)
{
overflowMonth = true;
throw new Exception();
};
Response.AppendCookie(new HttpCookie("downloadToken", filtro.DownloadToken));
return File(result, "application/vnd.ms-excel", "Manifesto.xls");
}
}
//...
I've never used NPOI so I may be wrong but what happens if you do:
var fileName = "Manifesto.xlsx";
return File(result, MimeMapping.GetMimeMapping(fileName), fileName);
or
return File(
result,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Manifesto.xlsx");
Here i am trying to open the file of any extension format in ASP.NET MVC CORE 2.0 that has been saved in data base according to the extension format of that file without downloading that file. For example lets say i have ms word file so when i click that file it should open in word, if i have pdf it should open in pdf format without downloading the file.
Now, the problem in my code is that it force to download the file instead of opening the file according to respective file extemsion format.
Any help will be a great and will be thank full.Thank You
Below is my code
public IActionResult ViewFileByFileId (int id)
{
DoctorCredentialDocsModel DoctorCredential = new DoctorCredentialDocsModel();
DoctorCredential = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, DoctorCredential.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
if (!strFileFullPath.Contains("..\\"))
{
byte[] filedata = System.IO.File.ReadAllBytes(strFileFullPath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = DoctorCredential.FileName,
Inline = false,
};
Request.HttpContext.Response.Headers.Add("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
else
{
return new NotFoundResult();
}
}
Try yo send like tihs. FileContentResult may can help you :)
Lastly look at this :)
What's the difference between the four File Results in ASP.NET MVC
public FileContentResult ViewFileByFileId (int id)
{
DoctorCredentialDocsModel DoctorCredential = new DoctorCredentialDocsModel();
DoctorCredential = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, DoctorCredential.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
if (!strFileFullPath.Contains("..\\"))
{
byte[] filedata = System.IO.File.ReadAllBytes(strFileFullPath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = DoctorCredential.FileName,
Inline = false,
};
Request.HttpContext.Response.Headers.Add("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
else
{
return new NotFoundResult();
}
}
I am creating an excel file on the fly for sending it an an attachment in an email. The relevant code snippet is provided below (It's a console app)
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
.............................................
.............................................
byte[] data = GetData(dt);
//save the data to a memory stream
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(ms, attachmentName, "application/vnd.ms-excel"));
....................................
....................................
//send email
smtpClient.Send(mailMsg); }
catch (Exception ex)
{
throw ex;
}
}
private static byte[] GetData(DataTable dt)
{
string strBody = DataTable2ExcelString(dt);
byte[] data = Encoding.ASCII.GetBytes(strBody);
return data;
}
private static string DataTable2ExcelString(System.Data.DataTable dt)
{
string excelSheetName = "Sheet1";
StringBuilder sbTop = new StringBuilder();
sbTop.Append("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" ");
sbTop.Append("xmlns=\" http://www.w3.org/TR/REC-html40\"><head><meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">");
sbTop.Append("<meta name=ProgId content=Excel.Sheet ><meta name=Generator content=\"Microsoft Excel 9\"><!--[if gte mso 9]>");
sbTop.Append("<xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>" + excelSheetName + "</x:Name><x:WorksheetOptions>");
sbTop.Append("<x:Selected/><x:ProtectContents>False</x:ProtectContents><x:ProtectObjects>False</x:ProtectObjects>");
sbTop.Append("<x:ProtectScenarios>False</x:ProtectScenarios></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets>");
sbTop.Append("<x:ProtectStructure>False</x:ProtectStructure><x:ProtectWindows>False</x:ProtectWindows></x:ExcelWorkbook></xml>");
sbTop.Append("<![endif]-->");
sbTop.Append("</head><body><table>");
string bottom = "</table></body></html>";
StringBuilder sbHeader = new StringBuilder();
//Header
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Columns[i].ColumnName + "</td>");
}
sbHeader.Append("</tr>");
//Items
for (int x = 0; x < dt.Rows.Count; x++)
{
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Rows[x][i] + "</td>");
}
sbHeader.Append("</tr>");
}
string data = sbTop.ToString() + sbHeader.ToString() + bottom;
return data;
}
This works but when I tried to open the excel file from the attachement, I receive:
I checked an found some solution in SO Post but could not make it to work. I tried like <x:DisplayAlerts>False</x:DisplayAlerts> but didn't work.
If the file you want to create and send doesn't have to be in exactly ".xls" format.. and if you are comfortable with ".xlsx" format... I think you might wanna try with EPPlus library, as it was mentioned Here. As I said you have to work with ".xlsx" (you can work with other excel formats but you'll get the same message about the file format when you open the file). So you can create the Excel file in temp folder with EPPlus using the DataTable as sorce and send the temp file by email... something like this for example:
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
string temp = Path.GetTempPath(); // Get %TEMP% path
string file = "fileNameHere.xlsx";
string path = Path.Combine(temp, file); // Get the whole path to the file
FileInfo fi = new FileInfo(path);
using (ExcelPackage pck = new ExcelPackage(fi))
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Table");
ws.Cells["A1"].LoadFromDataTable(dt, true);
pck.Save();
}
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(path, "application/vnd.ms-excel"));
try
{
//send email
smtp.Send(mailMsg);
}
catch (Exception)
{
//do smth..
}
finally
{
File.Delete(path);
}
}
catch (Exception ex)
{
throw ex;
}
}
I created a simple DataTable, sent it to myself in ".xlsx" format and was able to open it without any "Format warnings". I hope that helps.
The warning is display by MS Excel application because your file is not a real Excel file. It is an HTML with XLS extension. An XLS file is a binary file. MS Excel recognizes the HTML file and it display the file in its spreadsheet grid.
MS Excel displays security warnings for files that comes from external sources like email or internet.
The best solution is to use an Excel library that saves real Excel files in xls (old Excel file format) or xlsx (new Excel file format).
You can choose between free libraries like NPOI, EPPlus or commercial libraries like EasyXLS. Some of them saves only xls files, other only xlsx files and a few of them supports both file formats.
Solution to the warning / error “The file you are trying to open is in a different format than specified by the file extension”
Cause :
This happens because in the traditional Export to Excel method, the GridView is first converted to an HTML string and then that HTML string is exported to Excel. Thus originally it is not an Excel file hence the Excel Application throws the warning / error “The file you are trying to open is in a different format than specified by the file extension”.
Solution :
The solution to this problem is using ClosedXML library which is wrapper over the DocumentFormat.OpenXml library.
Dependency : OpenXml SDK 2.0 must be installed in system
You can get more help here :)
I have an application that allows a user to upload a file, the file is scanned with Symantec protection engine before it is saved. The problem I'm encountering is that after the files are scanned with protection engine they have 0 bytes. I'm trying to come up with a solution to this problem.
I've tried the cloning solution mentioned here: Deep cloning objects, but my uploaded files are not all Serializable. I've also tried resetting the stream to 0 in the scan engine class before passing it back to be saved.
I have been in contact with Symantec and they said the custom connection class that was written for this application looks correct, and protection engine is not throwing errors.
I'm open to any solution to this problem.
Here is the code where the file is uploaded:
private void UploadFiles()
{
System.Web.HttpPostedFile objFile;
string strFilename = string.Empty;
if (FileUpload1.HasFile)
{
objFile = FileUpload1.PostedFile;
strFilename = FileUpload1.FileName;
if (GetUploadedFilesCount() < 8)
{
if (IsDuplicateFileName(Path.GetFileName(objFile.FileName)) == false)
{
if (ValidateUploadedFiles(FileUpload1.PostedFile) == true)
{
//stores full path of folder
string strFileLocation = CreateFolder();
//Just to know the uploading folder
mTransactionInfo.FileLocation = strFileLocation.Split('\\').Last();
if (ScanUploadedFile(objFile) == true)
{
SaveFile(objFile, strFileLocation);
}
else
{
lblErrorMessage.Visible = true;
if (mFileStatus != null)
{ lblErrorMessage.Text = mFileStatus.ToString(); }
I can provide the connection class code if anyone needs that, but it is quite large.
You could take a copy of the filestream before you pass it into the scanning engine.
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
// pass the scanning engine
StreamScanRequest scan = requestManagerObj.CreateStreamScanRequest(Policy.DEFAULT);
//...
Update
To copy the stream you can do this:
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
file.InputStream.Position = ms.Position = 0;
I am using VS2005 C# and im trying to convert a pipe delimited text file to excel workbook format. Below is my code:
public partial class TextToExcel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SaveAsExcelBtn_Click(object sender, EventArgs e)
{
string xlExtension = ".csv";
string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss") + xlExtension;
// Before attempting to import the file, verify
// that the FileUpload control contains a file.
if (TextFile.HasFile)
{
// Get the name of the Excel spreadsheet.
string strFileName = Server.HtmlEncode(TextFile.FileName);
// Get the extension of the text.
string strExtension = Path.GetExtension(strFileName);
// Validate the file extension.
if (strExtension != ".TXT" && strExtension!=".txt")
{
Response.Write("<script>alert('Failed to import. Cause: Invalid text file.');</script>");
return;
}
// Generate the file name to save the text file.
//string strUploadFileName = "C:/Documents and Settings/rhlim/My Documents/Visual Studio 2005/WebSites/SoD/UploadFiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + strExtension;
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ';');
outputWriter.Write(fileContent);
TextFile.SaveAs(strExcelOutputFilename);
inputReader.Close();
}
//string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss")+xlExtension;
// Save the Excel spreadsheet on server.
//TextFile.SaveAs (strExcelOutputFilename);
}
else Response.Write("<script>alert('Failed to import. Cause: No file found');</script>");
}
}
Currently I am having some file saving errors
Any suggestions? Thanks a lot!
That's because Excel doesnt support pipelines you have to convert it so comma's or semicolumns like:
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ',');
outputWriter.Write(fileContent);
}
I googled and hope it will help you: http://csharp.net-informations.com/excel/csharp-create-excel.htm
Or, already answered: Create Excel (.XLS and .XLSX) file from C#
At the first link, the line xlWorkSheet.Cell[x,y] to put element in the dedicated cell.
FYI, xlsx format(new from Office 2007) will give you a great manipulation capability with code.
For generating and manipulating excel files, I personally prefer the NPOI library. Download it from Codeplex, add reference to the NPOI dlls to your project. Store a “template” excel file you would like in a known location, with the any column headers/formatting that you need. Then you just use npoi to make a copy of the template file and manipulate it at a sheet/row/column level and put whatever data you want.
The sample code snippet looks something like this. Assuming you have split your input into a List of strings
const string ExcelTemplateFile = "~/Resources/ExcelInputTemplate.xls";
const string ExcelWorksheetName = "Output Worksheet";
const int RequiredColumn = 1;
private HSSFWorkbook CreateExcelWorkbook(IEnumerable<String> inputData)
{
FileStream fs = new FileStream(Server.MapPath(ExcelTemplateFile), FileMode.Open, FileAccess.Read);
// Getting the complete workbook...
HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);
// Getting the worksheet by its name...
HSSFSheet sheet = templateWorkbook.GetSheet(ExcelWorksheetName);
int startRowIterator = 1;
foreach (string currentData in inputData)
{
sheet.CreateRow(startRowIterator).CreateCell(RequiredColumn).SetCellValue(currentData);
}
}