Загрузите файл excel со страницы через вызов WebApi
Я пытаюсь отправить файл 9 МБ .xls
в качестве ответа от метода контроллера веб-api. Пользователь нажимает кнопку на странице, и это приведет к загрузке через браузер.
Вот то, что у меня есть до сих пор, но оно не работает, но оно не вызывает никаких исключений.
[AcceptVerbs("GET")]
public HttpResponseMessage ExportXls()
{
try
{
byte[] excelData = m_toolsService.ExportToExcelFile();
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(excelData);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Data.xls"
};
return result;
}
catch (Exception ex)
{
m_logger.ErrorException("Exception exporting as excel file: ", ex);
return Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
Вот вызов jQuery jQuery coffeescript/javascript с помощью нажатия кнопки в интерфейсе.
$.ajax(
url: route
dataType: 'json'
type: 'GET'
success: successCallback
error: errorCallback
)
Теперь, когда я думаю об этом, возможно, dataType ошибочен и не должен быть json...
Ответы
Ответ 1
Мне пришлось сделать пару небольших изменений, чтобы заставить это работать
Сначала: измените метод на сообщение
[AcceptVerbs("POST")]
Второе: измените использование jQuery ajax lib для использования скрытой формы, здесь моя сервисная функция для выполнения скрытой формы и отправки ее.
exportExcel: (successCallback) =>
if $('#hidden-excel-form').length < 1
$('<form>').attr(
method: 'POST',
id: 'hidden-excel-form',
action: 'api/tools/exportXls'
).appendTo('body');
$('#hidden-excel-form').bind("submit", successCallback)
$('#hidden-excel-form').submit()
Надеюсь, там будет лучший способ сделать это, но пока он хорошо работает и загружает файл excel.
Ответ 2
Работает также как метод HTTP GET, но не использует $ajax, вместо этого используйте
window.open(URL);
Код С#:
[HttpGet]
[Route("report/{scheduleId:int}")]
public HttpResponseMessage DownloadReport(int scheduleId)
{
var reportStream = GenerateExcelReport(scheduleId);
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(reportStream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Schedule Report.xlsx"
};
return result;
}
Код JS:
downloadScheduleReport: function (scheduleId) {
var url = baseUrl + 'api/Tracker/report/' + scheduleId;
window.open(url);
}
Ответ 3
У меня возникла такая же проблема.
Проблема решена с помощью следующего:
window.open(url)
Ответ 4
//path to store Excel file temporarily
string tempPathExcelFile = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Hour + DateTime.Now.Minute +
DateTime.Now.Second + DateTime.Now.Millisecond +
"_temp";
try
{
//Get Excel using Microsoft.Office.Interop.Excel;
Excel.Workbook workbook = ExportDataSetToExcel();
workbook.SaveAs(tempPathExcelFile, workbook.FileFormat);
tempPathExcelFile = workbook.FullName;
workbook.Close();
byte[] fileBook = File.ReadAllBytes(tempPathExcelFile);
MemoryStream stream = new MemoryStream();
string excelBase64String = Convert.ToBase64String(fileBook);
StreamWriter excelWriter = new StreamWriter(stream);
excelWriter.Write(excelBase64String);
excelWriter.Flush();
stream.Position = 0;
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.Content = new StreamContent(stream);
httpResponseMessage.Content.Headers.Add("x-filename", "ExcelReport.xlsx");
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
httpResponseMessage.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = "BankingReport.xlsx";
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
}
catch (Exception ex)
{
_logger.ErrorException(errorMessage, ex);
return ReturnError(ErrorType.Error, errorMessage);
}
finally
{
if (File.Exists(tempPathExcelFile))
{
File.Delete(tempPathExcelFile);
}
}
//Javascript Code
$.ajax({
url: "/api/exportReport",
type: 'GET',
headers: {
Accept: "application/vnd.ms-excel; base64",
},
success: function (data) {
var uri = 'data:application/vnd.ms-excel;base64,' + data;
var link = document.createElement("a");
link.href = uri;
link.style = "visibility:hidden";
link.download = "ExcelReport.xlsx";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
error: function () {
console.log('error Occured while Downloading CSV file.');
},
});
In the end create an empty anchor tag at the end of your html file. <a></a>
Ответ 5
Это приведет к возврату файла при нажатии определенной кнопки
public FileResult ExportXls(){
//the byte stream is the file you want to return
return File(bytes, "application/msexcel")
}