MVC中的報表列印
不斷複製貼上word文件裡的特定表格塞資料
最後flush檔案供下載
如果不想慢慢數word檔中要擺放的位置,可直接用代碼取代的方式
Novacode權限層級比word檔本身設定還低的樣子
就算Novacode設定,有些細部格式(字型)都會已word檔主題為主
所以能先在word裡調好格式就少寫code省麻煩
ex:在word範本檔中的目標位置先寫「@Test@」,再用ReplaceText("@Test@", "我要填寫的內容在這")
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.MVC;
using ProjectName.Extensions; //一些模組化的雜七雜八,ex:this.HttpContext.取得清單()
using ProjectName.ViewModels;
using ProjectName.Models;
using System.Entity;
using Novacode; //去網路上下載dll檔匯入參考
using System.Drawing;
/// <summary>
/// Summary description for Class1
/// </summary>
public class 列印Controller : Controller
{
[DeleteFileAfterDownload]
public ActionResult 列印 (vmType vm, FormCollection fc, string command)
{
if (command == "print")
{
vm = (vmType)TempData["ViewVm"];
TempData.Keep("ViewVm");
FilePathResult file = null;
string 範本檔名稱 = Server.MapPath("~/TemplateFiles/") + "範本.docx";
string 暫存檔名稱 = Server.MapPath("~/Temp/") + Guid.NewGuid() + ".docx";
try
{
#region prepare data
IEnumerable<問題> ie問題 = this.HttpContext.取得清單().Where(x => x.作業序號 == this.HttpContext.取得作業序號());
#endregion
using (DocX doc = DocX.Load(範本黨名稱))
{
//複製一份範本文件供「貼上」時使用
DocX doc2 = doc.Copy();
//選擇字體
FontFamily f標楷體 = new FontFamily("DFKai-SB"); //標楷體代碼:DFKai-SB
int m = 1;
foreach (var empAns in vm.符合清單.Where(x => x.是否確認 == true))
{
//定位Table的資料位置
Table t = doc.Tables[0];
Paragraph p資料1 = t.Rows[1].Cells[0].Paragraphs[0];
Paragraph p資料2 = t.Rows[2].Cells[0].Paragraphs[0];
Paragraph p資料3 = t.Rows[3].Cells[0].Paragraphs[0];
Paragraph p資料4 = t.Rows[4].Cells[0].Paragraphs[0];
//寫入內容
p資料1.ReplaceText(".", "填表日期" + 日期); //用append有時會讓該列word格式跑掉,所以在原始檔裡面加個".",為保存格式改用取代方式
p資料2.Append(empAns.姓名).Font(f標楷體);
foreach(var liAns in empAns.詳細情況.OrderBy(x => x.問題序號))
{
if ( liAns.問題序號 == ie問題.Where(x => x.問題內容.Contains("事由")).Select(x => x.問題序號).FirstOrDefault() )
{
string 事由 = liAns.問題選項.選項名稱;
p資料3.Append(事由).FontSize(14);
}
}
//調整格式
p資料1.Alignment = Alignment.center;
t.Rows[1].Cells[0].VerticalAligment = VerticalAligment.Center;
//複製貼上新的表格
if(m< vm.符合清單.Where(x => x.是否確認 == true).Count())
{
//原始的table index為[0],複製的doc2.table[0]會插入在doc.table[0]前變成新的doc.table[0],
//而把舊的doc.table[0]往下擠成doc.table[1],以此類推
doc.Tables[0].InsertTableBeforeSelf(doc2.Tables[0]);
doc.Tables[0].InsertPageBreakAfterSelf();
m++;
}
}
doc.SaveAs(暫存檔名稱);
}
file = File(暫存檔名稱, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "匯出名稱.docx");
return file;
}
catch(Exception ex)
{
return View("Error", new HandleErrorInfo(ex, "controllerName", "actionName"));
}
}
}
}
public class DeleteFileAfterDownloadAttribute : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var fpr = filterContext.Result as FilePathResult;
filterContext.HttpContext.Response.Flush();
if (fpr != null)
{
System.IO.File.Delete(fpr.FileName);
}
}
}