__柯小呆。

我必须非常努力,才能看起来毫不费力。

导航

C#(MVC) Word 替换,填充表格,导出并下载PDF文档

Posted on 2015-09-28 17:58  柯小呆。  阅读(1532)  评论(0编辑  收藏  举报

近期做一个关于C# 操作 Word 模板 文档的功能模块,查阅资料,最终完美完成任务,记录下来,以便后面还会用到。

第一部分:为了防止动态数据,撑开样式,所以采用的是,无边框的word表格(表格属性-》边框和底纹-》边框(无))即可,A只是表示表格那儿有个单元格而已。

第二部分:用占位符,到时候用真实的数据来替换。

第三部分:产品项为动态生成。

 

下面看具体代码实现:

using Microsoft.Office.Interop.Word;

using WinForm = System.Windows.Forms;

public class XXController : BaseController
{

public ActionResult Print()
{
// pdf 路径
string PdfPath = AppDomain.CurrentDomain.BaseDirectory + "PurcharseContract.pdf";

// word模板地址
string WordTemplatePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\PurcharseContract.docx";

    // 定义WORD Application相关
    Application appWord = new Application
    {
        // WORD程序不可见
        Visible = false,

        // 不弹出警告框
        DisplayAlerts = WdAlertLevel.wdAlertsNone
    };

    lock (LockObj)
    {
        // 打开word模板文件
        Document doc = appWord.Documents.Open(WordTemplatePath, OMissing, false);

        try
        {

            Table table = doc.Tables[1];

            // 第1行
            table.Cell(1, 2).Range.Text = "名称";
            table.Cell(1, 4).Range.Text = "编号";

            // 第2行
            table.Cell(2, 2).Range.Text = "编码";
            table.Cell(2, 4).Range.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            // 准备需替换的数据
            Dictionary<string, string> datas = new Dictionary<string, string>();
            datas.Add("{PurchaseTotalMoney}", "500");
            datas.Add("{TotalMoneyChCapital}", GetChineseNum((decimal)500));


            // 替换占位符
            foreach (var data in datas)
            {
                SearchReplace(appWord, data.Key, data.Value);
            }

            // 2.填充产品项数据
            // 获取word文档里面的表格
            Table table = doc.Tables[2];

            // 第二行产品模板,插入产品项 行
            const int RowIdx = 2;
            foreach (var product in products.GroupBy(x => x.Name))
            {
                // 始终在第二行产品模板前插入新行
                object beforeRow = table.Rows[2];
                table.Rows.Add(ref beforeRow);

                foreach (var item in product)
                {
                    string info = "产品编码:ProductCode" + "\r产品名称:ProductName" + "\r规格型号:No";
                    string info2 = "单位:Unit" + "\r币别:RMB" + "\r品牌:AN";
                    string info3 = "单价:2" + "\r数量:2" + "\r金额:4";

                    table.Cell(RowIdx, 1).Range.Text = info;
                    table.Cell(RowIdx, 2).Range.Text = info2;
                    table.Cell(RowIdx, 3).Range.Text = info3;
                    table.Cell(RowIdx, 4).Range.Text = DateTime.Now.ToString("yyyy-MM-dd");
                    table.Cell(RowIdx, 5).Range.Text = "2";
                    table.Cell(RowIdx, 6).Range.Text = "2";
                    table.Cell(RowIdx, 7).Range.Text = "2.0";
                    table.Cell(RowIdx, 8).Range.Text = "备注";
                }
            }

            int count = table.Rows.Count;

            // 删除位于表格倒数第4行的产品模板项
            table.Rows[count - 3].Delete();

            double money = 200.00;

            // 运费
            table.Cell(count - 3, 3).Range.Text = (money * 0.02).ToString("F2");

            // 汇总
            table.Cell(count - 2, 3).Range.Text = money.ToString("F2");

            // 总金额(大写)
            table.Cell(count - 1, 2).Range.Text = GetChineseNum((decimal)money);

            // 3. 弹出 Windows 打印机选择项
            WinForm.PrintDialog pd = new WinForm.PrintDialog();
            if (pd.ShowDialog() != WinForm.DialogResult.Cancel)
            {
                // 设置选择的打印机名称
                appWord.ActivePrinter = pd.PrinterSettings.PrinterName;
            }

            // true后台打印,false前台打印。
            // 必须false,否则后台打印时,尚未打印,就调用了后续的Close,造成打印任务无法执行
            object printbackgroud = false;

            // 4. 开始打印
            doc.PrintOut(ref printbackgroud);

            // 5. 保存为PDF文档
            doc.ExportAsFixedFormat(PdfPath, WdExportFormat.wdExportFormatPDF);
        }
        catch (Exception ex)
        {
            //throw ex;
        }
        finally
        {
            // 关闭Word
            if (doc != null)
            {
                doc.Close(ref SaveOption);
            }

            // 退出word
            appWord.Quit(ref SaveOption);
        }
    }

    FileStream fs = new FileStream(PdfPath, FileMode.Open);

    // 6. 返回致客服端提供下载
    return File(fs, "application/octet-stream", "Test.pdf");
}

}
View Code

 

替换占位符字符串:

/// <summary>
/// 查找并替换文本
/// </summary>
/// <param name="app">word application</param>
/// <param name="strOldText">旧字符</param>
/// <param name="strNewText">新字符</param>
/// <returns>处理结果</returns>
public static bool SearchReplace(Application app, string strOldText, string strNewText)
{
    object replaceAll = WdReplace.wdReplaceAll;
    object missing = Type.Missing;

    // 首先清除任何现有的格式设置选项,然后设置搜索字符串 strOldText。  
    app.Selection.Find.ClearFormatting();
    app.Selection.Find.Text = strOldText;

    app.Selection.Find.Replacement.ClearFormatting();
    app.Selection.Find.Replacement.Text = strNewText;

    bool result = app.Selection.Find.Execute(
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref missing,
        ref replaceAll,
        ref missing,
        ref missing,
        ref missing,
        ref missing);

    return result;
}
View Code

 

附属功能,金额转中文大写:

/// <summary>
/// 金额小写转大写
/// </summary>
/// <param name="value">金额</param>
/// <returns>中文大写</returns>
public static string GetChineseNum(decimal value)
{
    const string Chinese = "零壹贰叁肆伍陆柒捌玖";
    const string Unit = "元十百千万十百千亿十百千兆十百千";
    const string Unit2 = "角分";

    StringBuilder builder = new StringBuilder();
    long u = 1;
    int i = 0;

    // 整数   
    while (value >= u)
    {
        int n = (int)((long)value / u % 10);
        u *= 10;
        if (n == 0)
        {
            i++;
            continue;
        }
        if (i > 1 && i < 4)
        {
            builder.Insert(0, "");
        }
        else if (i > 4 && i < 8)
        {
            builder.Insert(0, "");
        }
        else if (i > 8)
        {
            builder.Insert(0, "亿");
        }
        builder.Insert(0, Unit[i++]);
        builder.Insert(0, Chinese[n]);
    }

    // 小数   
    if ((long)value != value)
    {
        long value2 = (long)((value - (long)value) * 100);
        int n = (int)(value2 / 10 % 10);
        builder.Append(Chinese[n]);
        builder.Append(Unit2[0]);
        n = (int)(value2 % 10);
        builder.Append(Chinese[n]);
        builder.Append(Unit2[1]);
    }
    else
    {
        builder.Append("");
    }

    return builder.ToString();
}
View Code

 

参考博客:http://www.jb51.net/article/37615.htm

 

学无止境,共勉!!!