I have an AJAX file upload by call to MVC C# driver, but the browser refreshes and reloads the page.
But if I comment the line that saves the file in the driver does not happen that is only when the file is saved on the server. File.SaveAs (fname);
MVC controller:
[HttpPost]
public ActionResult UploadDocument()
{
if (Request.Files.Count > 0)
{
try
{
FileUpdateDto fileModal = new FileUpdateDto();
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
string fname;
DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Content/Document/" + UserId).ToString());
if (!directory.Exists)
{
Directory.CreateDirectory(Server.MapPath("~/Content/Document/" + UserId).ToString());
}
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
var guidnew = Guid.NewGuid();
fname = Path.Combine(Server.MapPath("~/Content/Document/" + UserId), guidnew + "." + fname.Split('.')[1].ToString());
fileModal.FileName = fname;
fileModal.Path = directory.ToString();
fileModal.DateFileUpload = DateTime.Now;
file.SaveAs(fname); // If I comment this line without refreshing the browser but does not save the file
}
return Json(fileModal);
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
Call Ajax in JavaScript:
UploadDocument: function () {
if (window.FormData !== undefined) {
var fileUpload = $("#AdviserFileUpload").get(0);
var files = fileUpload.files;
var fileData = new FormData();
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
//fileData.append('username', 'Manas');
$.ajax({
url: site.baseUrl + '/Api/Upload/Document',
type: "POST",
contentType: false,
processData: false,
data: fileData,
success: function (result) {
__this._AdviserDocumentFile = result;
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
}
I believe I found the solution. The cause is that Visual Studio's "Enable Reload on Save" property is True.
Go to Tools - Options - Web - Browser Reload on Save - Enable Reload on Save and make it false.
Im working with VS2015 and this worked for me, hope it works for you too.
Source
I'm developing an app which can generate a excel file using html table. Up to now I developed html table download as excel file part. (This happens in client side with javascript). Now I need to send email with that attachment (The excel file) to particular person's email address. So I'm confuse how to do this, because up to now I generate excel in client side and need to send that file via email. In this case is it needed to copy client side excel to the server? If so how to do this?
Please give me a direction.
Update 1 (Adding codes)
This is the javascript, that I used to download html table as excel to client side.
var tablesToExcel = (function () {
var uri = 'data:application/vnd.ms-excel;base64,'
, tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }
return function (tables, wsnames, wbname, appname) {
var ctx = "";
var workbookXML = "";
var worksheetsXML = "";
var rowsXML = "";
for (var i = 0; i < tables.length; i++) {
if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
for (var j = 0; j < tables[i].rows.length; j++) {
rowsXML += '<Row>'
for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
dataValue = (dataValue) ? dataValue : tables[i].rows[j].cells[k].innerHTML;
var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
dataFormula = (dataFormula) ? dataFormula : (appname == 'Calc' && dataType == 'DateTime') ? dataValue : null;
ctx = {
attributeStyleID: (dataStyle == 'Currency' || dataStyle == 'Date') ? ' ss:StyleID="' + dataStyle + '"' : ''
, nameType: (dataType == 'Number' || dataType == 'DateTime' || dataType == 'Boolean' || dataType == 'Error') ? dataType : 'String'
, data: (dataFormula) ? '' : dataValue
, attributeFormula: (dataFormula) ? ' ss:Formula="' + dataFormula + '"' : ''
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>'
}
ctx = { rows: rowsXML, nameWS: wsnames[i] || 'Sheet' + i };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
}
ctx = { created: (new Date()).getTime(), worksheets: worksheetsXML };
workbookXML = format(tmplWorkbookXML, ctx);
var link = document.createElement("A");
link.href = uri + base64(workbookXML);
link.download = wbname || 'Workbook.xls';
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
})();
Still I do not have idea to save generated excel to server and send it as email.
AS per our discussion:
1. you need to send data from client to server
you can use this code to do this sending headers and values to server using ajax and you can also filter columns as you want
function SaveToServer() {
var gov = GetHeaders('tbl');
$.ajax({
url: '#Url.Content("~/Home/ReciveData")',
data: { headers: JSON.stringify(gov.heasers), data: JSON.stringify(gov.data) },
success: function (data) {
// Success
},
error: function (xhr) {
}
});
}
function GetHeaders(tableName) {
table = document.getElementById(tableName);
var tbl_Hdata = [];
var tbl_Data = [];
for (var i = 0, row; row = table.rows[i]; i++) {
var rowData = [];
for (var j = 0, col; col = row.cells[j]; j++) {
// add column filter
if (i == 0) {
tbl_Hdata.push(col.innerHTML);
}
else {
rowData.push(col.innerHTML);
}
}
if (i > 0) {
tbl_Data.push(rowData);
}
}
return { heasers: tbl_Hdata, data: tbl_Data };
}
now we want to recive this data and convert it to datatable to save it to excel in server side
using NPOI
public void ReciveData(string headers, string data)
{
#region Read Data
List<string> tbl_Headers = new List<string>();
List<List<string>> tbl_Data = new List<List<string>>();
tbl_Headers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(headers);
tbl_Data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<List<string>>>(data);
#endregion
#region Create Data Table
DataTable dataTable = new DataTable("Data");
foreach (var prop in tbl_Headers)
{
dataTable.Columns.Add(prop);
}
DataRow row;
foreach (var rw in tbl_Data)
{
row = dataTable.NewRow();
for (int i = 0; i < rw.Count; i++)
{
row[tbl_Headers[i]] = rw[i];
}
dataTable.Rows.Add(row);
}
#endregion
#region Save To excel
string path = #"D:\";
string fileName = "";
GenerateExcelSheetWithoutDownload(dataTable, path, out fileName);
#endregion
}
public bool GenerateExcelSheetWithoutDownload(DataTable dataTable, string exportingSheetPath, out string exportingFileName)
{
#region Validate the parameters and Generate the excel sheet
bool returnValue = false;
exportingFileName = Guid.NewGuid().ToString() + ".xls";
if (dataTable != null && dataTable.Rows.Count > new int())
{
string excelSheetPath = string.Empty;
#region Check If The directory is exist
if (!Directory.Exists(exportingSheetPath))
{
Directory.CreateDirectory(exportingSheetPath);
}
excelSheetPath = exportingSheetPath + exportingFileName;
FileInfo fileInfo = new FileInfo(excelSheetPath);
#endregion
#region Write stream to the file
MemoryStream ms = DataToExcel(dataTable);
byte[] blob = ms.ToArray();
if (blob != null)
{
using (MemoryStream inStream = new MemoryStream(blob))
{
FileStream fs = new FileStream(excelSheetPath, FileMode.Create);
inStream.WriteTo(fs);
fs.Close();
}
}
ms.Close();
returnValue = true;
#endregion
}
return returnValue;
#endregion
}
private static MemoryStream DataToExcel(DataTable dt)
{
MemoryStream ms = new MemoryStream();
using (dt)
{
#region Create File
HSSFWorkbook workbook = new HSSFWorkbook();//Create an excel Workbook
ISheet sheet = workbook.CreateSheet("data");//Create a work table in the table
int RowHeaderIndex = new int();
#endregion
#region Table Headers
IRow headerTableRow = sheet.CreateRow(RowHeaderIndex);
if (dt != null)
{
foreach (DataColumn column in dt.Columns)
{
headerTableRow.CreateCell(column.Ordinal).SetCellValue(column.Caption);
}
RowHeaderIndex++;
}
#endregion
#region Data
foreach (DataRow row in dt.Rows)
{
IRow dataRow = sheet.CreateRow(RowHeaderIndex);
foreach (DataColumn column in dt.Columns)
{
dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
}
RowHeaderIndex++;
}
#endregion
workbook.Write(ms);
ms.Flush();
//ms.Position = 0;
}
return ms;
}
Now you can send this file as attachment in mail
You can't create Excel files with HTML tables. This is a hack that's used to fake actual Excel files. Excel isn't fooled, it recognizes the HTML file and tries to import the data using defaults. This will easily break for any number of reasons, eg different locale settings for decimals and dates.
Excel files are just zipped XML files. You can create them using XML manipulation, the Open XML SDK or a library like EPPlus.
Creating an Excel file with EPPlus is as easy as calling the LoadFromCollection or LoadFromDatatable method. The sheet can be saved to any stream, including FileStream or MemoryStream. A MemoryStream can be used to send the data to a web browser as shown in this answer:
public ActionResult ExportData()
{
//Somehow, load data to a DataTable
using (ExcelPackage package = new ExcelPackage())
{
var ws = package.Workbook.Worksheets.Add("My Sheet");
//true generates headers
ws.Cells["A1"].LoadFromDataTable(dataTable, true);
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
Mail attachments can also be created from a MemoryStream. The Attachment(Stream, string,string) constructor accepts any stream as input. The example above could be modified to create an attachment instead of sending the data to the browser:
public void SendData(string server, string recipientList)
{
//Same as before
using (ExcelPackage package = new ExcelPackage())
{
var ws = package.Workbook.Worksheets.Add("My Sheet");
ws.Cells["A1"].LoadFromDataTable(dataTable, true);
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
SendExcel(server,recipientList);
}
}
void SendExcel(string server, string recipientList)
{
//Send the file
var message = new MailMessage("logMailer#contoso.com", recipientList);
message.Subject = "Some Data";
Attachment data = new Attachment(stream, name, contentType);
// Add the attachment to the message.
message.Attachments.Add(data);
// Send the message.
// Include credentials if the server requires them.
var client = new SmtpClient(server);
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Send(message);
}
}
UPDATE
Generating an XSLX table on the client side becomes a lot easier if you use a library like js-xlsx. There's even a sample that generates an XLSX file from an HTML table
i want to upload multiple pdf files in one file upload control in asp.net and then merg it ,
this is already done when i pass static path and file name
how to do that dynamically
my code is here
if (FileUpload1.HasFile)
{
try
{
HttpFileCollection uploadedVideoFiles = Request.Files;
// Get the HttpFileCollection
for (int i = 0; i < uploadedVideoFiles.Count; i++)
{
HttpPostedFile hpfiles = uploadedVideoFiles[i];
string fname = Path.GetFileName(hpfiles.FileName);
if (hpfiles.ContentLength > 0)
{
hpfiles.SaveAs(Server.MapPath("~/Images/") + Path.GetFileName(hpfiles.FileName));
hpfiles.SaveAs(Server.MapPath(Path.Combine(#"~/Images/", fname)));
string filepath = Server.MapPath(#"~/Images/");
string path = filepath + fname;
}
}
String[] files = #"C:\ENROLLDOCS\A1.pdf,C:\ENROLLDOCS\A#.pdf".Split(',');
MergeFiles(#"C:\ENROLLDOCS\New1.pdf", files);// merg is a method which merg 2 or more than 2 documents
}
catch (Exception ex)
{
Label1.Text = "The file could not be uploaded. The following error occured: " + ex.Message;
}
}
You will need to collect values of path in a List<string> and then pass the result to MergeFiles().
I don't quite follow your code (you'll need to clean it up a bit), but what you need is basically this:
var fileNames =
uploadedVideoFiles.
Select(uvf => {
var fileName = Path.GetFileName(hpfiles.FileName);
var destinatonPath = Path.Combine(Server.MapPath("~/images"), fileName);
uvf.SaveAs(destinatonPath);
return destinationPath;
}).
ToArray();
MergeFiles(#"C:\ENROLLDOCS\New1.pdf", fileNames);
Beware of duplicating file names in ~/images, though.
In the next javascript code i have a function to open a file(xml) and then it will search for all the occurences that are between a specific tag(<file>). After using a Regex expression to get the filenames, i need that the dialog can be open, automatically, the same number of times of the files discovered in the xml file. The objective is to force the user to search in their local directory for the files that are in the xml file. After this i will send the strings to the server side.
function fileSelected(evt) {
var files = evt.target.files;
var reader = new FileReader();
var bol;
if (document.getElementById("fileToLoad").value == "") {
alert("Please select a file before submitting.");
bol = 0;
}
else {
ext = document.getElementById("fileToLoad").value;
fpath = ext;
ext = ext.substring(ext.length - 3, ext.length);
ext = ext.toLowerCase();
if (ext == 'xml')
bol = 1;
else if (ext == 'rdf')
bol = 1;
else {
alert("You selected a ." + ext + " file; this is not allowed.");
bol = 0;
}
}
if (bol == 1) {
reader.onload = function (event) {
editor.setValue(event.target.result);
var teste = editor.getValue();
getFileName(teste);
var debug = event.target.files;
document.getElementById("Procura").style.visibility = "visible";
//document.getElementById('<%=hf.ClientID%>').value = editor.getValue();
}
reader.readAsText(files[0], "UTF-8");
}
return false;
}
function getFileName(str) {
var matches = str.match(/<file>(.*)<\/file>/g);
var len = matches.length, i, result;
for (i = 0; i < len; i++) {
matches[i] = matches[i].replace(/<[\/]{0,1}(file|FILE)[^><]*>/g, "");
//need to open dialog for user to search for the same file in matches[i]
//after get file, will save on a string in order to send to server
}
}
I´ve tried many things but this is my first steps in this world(js/jquery/html).
I have 2 file upload controller I have problem when both of them have files one hasFile value equal true and other equal false can someone help me.
if (fuPDFDoc.HasFile)
{
String fileName = fuPDFDoc.FileName;
savePathPDF_Resouce += fileName;
fuPDFDoc.SaveAs(Server.MapPath(savePathPDF_Resouce));
}
if (fupdfVocabularyURL.HasFile)
{
String fileName = fupdfVocabularyURL.FileName;
savePathPDF_Vocab += fileName;
fupdfVocabularyURL.SaveAs(Server.MapPath(savePathPDF_Vocab));
}
r.PdfDocURL = savePathPDF_Resouce.ToString();
r.pdfVocabularyURL = savePathPDF_Vocab.ToString();
r.ResourceID = Resoursce.Insert(r);
I think you have to refer directly to the files collection, e.g. like this:
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
hpf.SaveAs(Server.MapPath("MyFiles") + "\\" + Path.GetFileName(hpf.FileName));
}
}