OpenXml 등 stream 을 지원하는 객체를 사용자의 컴퓨터에 파일로 다운로드 하기 위한 레이저 컴포넌트 예제입니다.
js 를 통해 구현되었고, js 는 콜레이션 파일에 두었습니다.
./Component/StreamDownloader.razor
@inject IJSRuntime JS
@implements IAsyncDisposable
@code {
IJSObjectReference? _module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
_module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Component/StreamDownloader.razor.js");
}
}
public async Task StartAsync(string fileName, Stream stream)
{
if(_module is not null)
{
using var streamRef = new DotNetStreamReference(stream);
await _module.InvokeVoidAsync("downloadStream", fileName, streamRef);
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if(_module is not null)
{
// for client-side blazor
await _module.DisposeAsync();
// if server-side blazor
// try
// {
// await _module.DisposeAsync();
// }
// catch (JSDisconnectedException)
// {
// // trap exception from websocket connection failure
// }
}
}
}
아래는 콜레이션 js 파일입니다.
./Component/StreamDownloader.razor.js
export async function downloadStream(fileName, contentStreamReference) {
const arrayBuffer = await contentStreamReference.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
const anchr = document.createElement('a');
anchr.href = url;
anchr.download = fileName ?? '';
anchr.click();
anchr.remove();
URL.revokeObjectURL(url);
}
사용코드
Home.razor
@using System.Text;
<StreamDownloader @ref="_downLoader" />
<button class="btn btn-primary" @onclick="ExecuteDownload">Download</button>
@code {
StreamDownloader? _downLoader;
private async void ExecuteDownload()
{
var content = "Hello world";
var bytes = Encoding.UTF8.GetBytes(content);
using var stream = new MemoryStream(bytes);
if (_downLoader is not null)
await _downLoader.StartAsync("test.txt", stream);
}
}
참조