公司專案中,多有需求要查詢報表或作文檔的套印,因此需要在頁面上回傳檔案樓作另開頁面列印或套印檔案的下載,此篇會提及回傳檔案流的擴充方法,以及前端ajax接收檔案流的寫法。
回傳下載檔案流
檔案流擴充
我們可以透過MemoryStream將檔案透過選定格式讀成檔案流
/// <summary>
/// 取得文件匯出的 FileStream
/// </summary>
/// <param name="doc"></param>
/// <param name="saveFormat"></param>
/// <returns></returns>
public static System.IO.MemoryStream GetFileStream(this Document doc, Aspose.Words.SaveFormat saveFormat)
{
var fileStream = new System.IO.MemoryStream(); // new 檔案流
doc.Save(fileStream, saveFormat); // 將文檔以saveFormat傳到fileStream
fileStream.Position = 0; // 將MemoryStream讀取的位置設回開頭
return fileStream;
}
其中,SaveFormat為Aspose提供的儲存格式,可以選定Aspose提供的枚舉值來設定讀取檔案流的格式
也可以在擴充內透過switch來針對不同的saveformat做不同處理:
/// <summary>
/// 取得文件匯出的 FileStream
/// </summary>
/// <param name="workbook"></param>
/// <param name="saveFormat"></param>
/// <returns></returns>
public static System.IO.MemoryStream GetFileStream(this Workbook workbook, Aspose.Cells.SaveFormat saveFormat)
{
var fileStream = new System.IO.MemoryStream();
switch (saveFormat)
{
case Aspose.Cells.SaveFormat.Csv:
var saveOptions = new TxtSaveOptions { Encoding = Encoding.UTF8 };
workbook.Save(fileStream, saveOptions);
break;
default:
workbook.Save(fileStream, saveFormat);
break;
}
fileStream.Position = 0;
return fileStream;
}
如此,便可以取得該檔案的檔案流!
回傳檔案流結果
在MVC專案中,也有回傳檔案專用的Result,可以給定檔案流及回傳格式來回傳檔案至前端
/// <summary>
/// 取得doc檔匯出串流
/// </summary>
/// <returns></returns>
public ActionResult ExportDocxFile()
{
var data = _FakeMultiLayerList.FakeListForBind(); // 假資料
var doc = new Document("test.docx"); // 開啟範例文檔
doc.BindData(data); // 透過擴充方法套印檔案 -> 也可做其他檔案操作
doc.Save("bindedDoc.docx", Aspose.Words.SaveFormat.Docx);
return File(doc.GetFileStream(Aspose.Words.SaveFormat.Docx), "application/docx"); // 回傳contentType為"application/docx"的檔案流
}
接著在view頁面透過ajax呼叫該action
<script>
// 匯出docx
function ExportDocxFile() {
$.ajax({
url: '@Url.Action("ExportDocxFile", "Home")', // 呼叫的url
type: 'POST',
xhrFields: {
responseType: 'blob' // 回傳為二進制的數據
},
success: function (response) {
// 下載部分
if (response instanceof Blob) { // 若為blob
var blob = new Blob([response], { type: 'application/octet-stream' }); // 建一個'application/octet-stream'的blob物件來接回傳數據
// 生臨時url
var url = URL.createObjectURL(blob);
var downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = 'Binded.docx'; // 設定下載名稱
downloadLink.click(); // 自動點擊來做下載
location.reload();
}
else { // 回傳非Blob的其他處理
ShowMessageBlock("查無!");
}
},
error: function (error) {
console.log(error);
}
});
}
</script>
在前端呼叫該function後,瀏覽器會自動下載符合格式的檔案
回傳檔案html另開頁面套印
回傳html
我們透過Aspose的save將檔案存成html格式,再透過StreamReader將讀取內容存到content,回傳Content Result
/// <summary>
/// 列印
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ActionResult Print()
{
var data = _FakeMultiLayerList.FakeListForBind();
// 開啟範例文檔
var doc = new Document("test.docx");
doc.BindData(data);
doc.Save("bindedDoc.docx", Aspose.Words.SaveFormat.Docx);
// 如果有資料
if (doc != null)
{
// 轉html字串
var content = string.Empty;
// 利用StreamReader將檔案讀成html格式
using (StreamReader reader = new StreamReader(doc.GetFileStream(Aspose.Words.SaveFormat.Html)))
{
content = reader.ReadToEnd(); // 將讀取內容存到content
}
return Content(content); // 回傳字串結果
}
else
{
return Json(new { nodata = true });
}
}
前端接收html字串另開頁面套印
前端部分,先透過回傳格式來判斷流程,若回字串塞到頁面上hidden的html容器,並透過printpage列印
<script>
// 列印證明冊
function PrintDocxFile() {
var url = '@Url.Action("Print", "Home")';
$.ajax({
url: url,
type: 'GET',
success: function (response) {
debugger
if (typeof response === 'string') {
$('#PrintContainer').html(response);
printpage('PrintContainer');
}
else {
ShowMessageBlock("查無資料!");
}
},
error: function (error) {
console.log(error);
}
});
}
</script>
如此便可將檔案顯示在頁面上,或透過jquery使用瀏覽器的列印。
結語
透過GetFileStream的擴充,我們可以針對要回傳的格式作個別的操作。這邊要特別注意ajax接收的格式,要與action回傳的檔案流格式相容。
另外,若在練習時,aspose沒有憑證的狀況,會有浮水印,這會導致doc在做save成html時,因為浮水印圖檔導致報錯,可以透過設定圖檔檔案流選單的設置來避開,後續有機會會再對aspose的眉眉角角開系列><