我用ASP.NET c#和angular 8开发了一个web API。我尝试在服务器端(使用NPOI)将一些数据从Oracle导出到Excel文件,并在客户端下载。我可以看到内存流有数据,但是在“返回响应”中,它没有返回给客户端,而是再次调用了函数。这是我的代码:
超文本标记语言:
<button
class="col-sm-2 button-style button-text"
style="color: white; background-color: #19D893;height: 100%;"
(click)="exportPriceList()">
Export
</button>
键入脚本:
public exportPriceList(): void {
let fileName='filename';
const fileType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
console.log('before promise');
const promise = new Promise((resolve, reject) => {
this.export().subscribe(
success => {
console.log('start success');
const blob = new Blob ([success], {type: fileType});
console.log('window.navigator ', window.navigator );
console.log('window.navigator.msSaveOrOpenBlob ', window.navigator.msSaveOrOpenBlob );
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, );
} else {
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = fileName ;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
},
err => {
alert(err);
});
});
promise.then((res) => {
console.log('promise!!!! ', res );
});
promise.catch((err) => {
});
}
public export()
{
console.log('start export to excel');
const fileName = 'filename1';
const fileType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
const url = this.apiService.baseUrl + 'api/PriceList/Export?token=' + this.auth.authDetails.getValue().token +
'&priceListType=' + this.selectedPriceListType.Key + '&fileType=' + fileType + '&bank=' + this.selectedBank.Key;
return this.http.get(url, {responseType: 'arraybuffer'});// this.http.get(url, {responseType: 'blob'});
}
API 控制器:
[HttpGet]
[Route("api/PriceList/Export")]
public HttpResponseMessage Export([FromUri]string token, [FromUri]int priceListType,[FromUri]string fileType, [FromUri]int? bank=null)
{
try
{
var stream = dal.ExportPriceListServer(priceListType, bank);
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName= "PriceList_" + bank + "_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx"
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(fileType);
return response;
}
catch (Exception ex)
{
exc.throwException(EventLogEntryType.Error, ex.ToString());
throw;
}
}
DAL:(生成excel的最后一个函数。)
public MemoryStream ExportToExcel(DataTable dt)
{
try
{
using (var stream = new MemoryStream())
{
// Declare XSSFWorkbook object for create sheet
var workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet("sheet 1");
int rowIndex = 0;
var headerRow = sheet.CreateRow(1);
//Below loop is create header
foreach (DataColumn column in dt.Columns)
{
XSSFCell xc = (XSSFCell)headerRow.CreateCell(column.Ordinal);
xc.SetCellValue(GetColumnTitle(column.ColumnName));
//xc.CellStyle = xstl;
}
rowIndex = 2;
foreach (DataRow row in dt.Rows)
{
XSSFRow dataRow = (XSSFRow)(sheet.CreateRow(rowIndex));
foreach (DataColumn column in dt.Columns)
{
XSSFCell c = (XSSFCell)dataRow.CreateCell(column.Ordinal);
string val = row[column].ToString();
int x;
if (Int32.TryParse(val, out x) && (!String.IsNullOrEmpty(val)))//column.IsNumeric()
{
c.SetCellValue(Int64.Parse(val));
c.SetCellType(CellType.Numeric);
}
else
{
c.SetCellValue(row[column].ToString());
}
// no need to auto size all the time, after 100 is ok... (it costs a lot)
if (rowIndex == 100)
{
sheet.AutoSizeColumn(column.Ordinal);
}
}
rowIndex++;
}
// Declare one MemoryStream variable for write file in stream
workbook.Write(stream, true);
return stream;
}
}
catch (Exception ex)
{
Console.Write(ex);
return null;
}
}
这是我在chrome调试器中看到的:[Network][1]
在《计时》中,我看到了“失速”:[失速][2]
rates.component.ts:100 before promise
zone.js:2969 GET ..... **net::ERR_CONNECTION_RESET**
scheduleTask @ zone.js:2969
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
onScheduleTask @ zone.js:297
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:401
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:3001
proto.<computed> @ zone.js:1394
(anonymous) @ http.js:1630
push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe
@可观察.js:43 推送。/node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29 push../node_modules/rxjs/_esm5/internal/operator/finalize.js.最后操作员.call @ finalize.js:13 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24 (anonymous) @ subscribeTo.js:21 subscribeToResult @ subscribeToResult.js:11 push../node_modules/rxjs/_esm5/internal/operators /mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js:74 push../node_modules/rxjs/_esm5/internal/operators /mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js:68 push../node_modules/rxjs/_esm5/internal/operators /mergeMap.js.MergeMapSubscriber._next @ mergeMap.js:51 push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54 (anonymous) @ scalar.js:5 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe @ Observable.js:43 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29 push../node_modules/rxjs/_esm5/internal/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js:29 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24 push../node_modules/rxjs/_esm5/internal/operator/filter.js.FilterOperator.call @ filter.js:15 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24 push../node_modules/rxjs/_esm5/internal/operators /map.js.MapOperator.call @ map.js:18 push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24 (anonymous) @ rates.component.ts:144 ZoneAwarePromise @ zone.js:891 push../src/app/Components/content/rates/rates.component.ts.RatesComponent.exportPriceList @ rates.component.ts:143 eval @ RatesComponent.html:100 handleEvent @ core.js:19545 callWithDebugContext @ core.js:20639 debugHandleEvent @ core.js:20342 dispatchEvent @ core.js:16994 (anonymous) @ core.js:17441 (anonymous) @ platform-browser.js:993 push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421 onInvokeTask @ core.js:14051 push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420 push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188 push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496 invokeTask @ zone.js:1540 globalZoneAwareCallback @ zone.js:1566
你有什么解决办法吗?
谢谢,
我解决了这个问题。我修改了代码:
API控制器:
MemoryStream stream = dal.ExportPriceListServer(priceListType);
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new ByteArrayContent(stream.ToArray());
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "test.xlsx"
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(fileType);
return response;
DAL:使用Just编写流
// Declare one MemoryStream variable for write file in stream
using (var stream = new MemoryStream())
{
workbook.Write(stream, true);
return stream;
}
本文向大家介绍Asp.Net使用Npoi导入导出Excel的方法,包括了Asp.Net使用Npoi导入导出Excel的方法的使用技巧和注意事项,需要的朋友参考一下 asp.net针对Excel文件的导入与导出是非常常见的功能之一。本文实例讲述了Asp.Net使用Npoi导入导出Excel的方法。分享给大家供大家参考之用。具体方法如下: 在使用Npoi导出Excel的时候,服务器可以不装任何offi
为什么我在下面的代码段中的X轴上有一个溢出? 在我的网格容器上应用时,就会产生溢出。 null null https://codepen.io/anon/pen/wdjexz?editors=1100
本文向大家介绍c# 将Datatable数据导出到Excel表格中,包括了c# 将Datatable数据导出到Excel表格中的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!
问题内容: 好吧,我试图理解并阅读可能导致它的原因,但我却无法理解: 我的代码中有这个地方: 事实是,当它尝试调用某些方法时,它将引发而不是其他预期的异常(特别是)抛出 。我实际上知道调用了什么方法,所以我直接转到该方法代码,并为应该抛出的行添加了一个块 ,它实际上按预期抛出。然而,当它上升时,以某种方式更改了上面的代码并没有 按预期进行。 是什么原因导致这种行为的?我该如何检查? 问题答案: 通
问题内容: 即使模型类中没有验证约束,我也会收到此错误(所有成员变量均已正确设置,但我在创建对象时仍然遇到此异常)。如何调试此错误? 问题答案: 每个都有一个数组。每个显示了您要保留的bean的哪个属性被侵犯。正如@Arthur正确指出的那样,违反Java持久性注释的结果也以s 结尾。 要调试你的问题,我会暂时赶在并打印出每个如下:
问题内容: 带有此文件的ImageIO.read(imagePath)给出了CMMException,为什么Java无法处理此看似有效的文件http://www.jthink.net/jaikoz/scratch/front.jpg 问题答案: 我想我掌握了您的问题。我检查了您链接的图像(http://www.jthink.net/jaikoz/scratch/front.jpg)。其归因于Exi