百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

使用Spire.Doc组件利用模板导出Word文档

citgpt 2024-10-26 08:39 21 浏览 0 评论

以前一直是用Office的组件实现Word文档导出,但是让客户在服务器安装Office,涉及到版权;而且Office安装,包括权限配置也是比较麻烦。

     现在流行使用第三方组件来实现对Office的操作,有NPOI,Spire等第三方组件。开始考虑的是NPOI,毕竟它在操作Excel方面还是很强大的;但是不知道是它本身没有,还是我没找到,无法实现利用Word模板的标签插入内容,纯靠代码去生成Word文档,排版是个大问题。最终找到了Spire.Doc组件,轻松实现!

  Spire的官网地址:https://www.e-iceblue.com/

1、项目中引用 Free Spire.Doc 组件,我是直接用NuGet下载包的.

安装完后,会引用其三个组件:

2、Word 模板制作

打开Word,点击 文件->选项->自定义功能区,勾选上“开发工具”:

主要使用文本域控件,插入作为标签:

如果有需要,可以添加“下划线”,或者“字符边框”等效果:

底下三个,前2个我用的是开发工具中的复选框(窗体控件)效果不是勾选的,是×号,效果不是客户想要的,所以使用了第二种解决方案“字符边框”,最后看导出的效果:

3、代码

可重用代码:

using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace We.Framework.Spire
{
    /// <summary>
    /// Sprie.Doc
    /// Designed by XIAO
    /// 2017-05-09
    /// </summary>
    public class WordHandler
    {
        public static bool ExportWordByFields<T>(T mod, string TempleteFilePath, string ExpFilePath)
        {
            if (mod == null)
            {
                throw new Exception("模型为空!");
            }

            System.Reflection.PropertyInfo[] properties = mod.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            if (properties.Length <= 0)
            {
                throw new Exception("模型属性为空!");
            }

            if (!File.Exists(TempleteFilePath))
            {
                throw new Exception("指定路径的模板文件不存在!");
            }

            try
            {
                Document doc = new Document();
                doc.LoadFromFile(TempleteFilePath);

                #region 替换文字
                //doc.Replace("海关", "海关口岸", true, true);
                //doc.Replace("报验", "报检", true, true);
                #endregion

                //清除表单域阴影
                doc.Properties.FormFieldShading = false;

                //遍历Word模板中的文本域(field.name为文本域名称)
                foreach (FormField field in doc.Sections[0].Body.FormFields)
                {
                    foreach (System.Reflection.PropertyInfo prop in properties)
                    {
                        string name = prop.Name; //属性名称
                        object value = prop.GetValue(mod, null);  //属性值
                        string des = ((DescriptionAttribute)Attribute.GetCustomAttribute(prop, typeof(DescriptionAttribute))).Description;// 属性描述值

                        //注意:文本域名称 == 模型中属性的 Description 值 !!!!!!
                        //也可以: 文本域名称 == 模型中属性的 Name 值 !!!!!!
                        if (field.Name == des)
                        {
                            if (field.DocumentObjectType == DocumentObjectType.TextFormField)   //文本域
                            {
                                if (prop.PropertyType.Name == "Boolean")
                                {
                                    field.Text = "√";   //插入勾选符号
                                    break;
                                }
                                else
                                {
                                    field.Text = value.ToString();   //向Word模板中插入值
                                    break;
                                }
                            }
                            else if (field.DocumentObjectType == DocumentObjectType.CheckBox)   //复选框
                            {
                                (field as CheckBoxFormField).Checked = (value as bool?).HasValue ? (value as bool?).Value : false;
                            }
                        }
                    }
                }

                doc.SaveToFile(ExpFilePath, FileFormat.Docx);
                doc.Close();

                return true;
            }
            catch (Exception ex)
            {
                string msg = ex.Message;

                return false;
            }
        }
    }
}

3、代码

可重用代码:

using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace We.Framework.Spire
{
    /// <summary>
    /// Sprie.Doc
    /// Designed by XIAO
    /// 2017-05-09
    /// </summary>
    public class WordHandler
    {
        public static bool ExportWordByFields<T>(T mod, string TempleteFilePath, string ExpFilePath)
        {
            if (mod == null)
            {
                throw new Exception("模型为空!");
            }

            System.Reflection.PropertyInfo[] properties = mod.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            if (properties.Length <= 0)
            {
                throw new Exception("模型属性为空!");
            }

            if (!File.Exists(TempleteFilePath))
            {
                throw new Exception("指定路径的模板文件不存在!");
            }

            try
            {
                Document doc = new Document();
                doc.LoadFromFile(TempleteFilePath);

                #region 替换文字
                //doc.Replace("海关", "海关口岸", true, true);
                //doc.Replace("报验", "报检", true, true);
                #endregion

                //清除表单域阴影
                doc.Properties.FormFieldShading = false;

                //遍历Word模板中的文本域(field.name为文本域名称)
                foreach (FormField field in doc.Sections[0].Body.FormFields)
                {
                    foreach (System.Reflection.PropertyInfo prop in properties)
                    {
                        string name = prop.Name; //属性名称
                        object value = prop.GetValue(mod, null);  //属性值
                        string des = ((DescriptionAttribute)Attribute.GetCustomAttribute(prop, typeof(DescriptionAttribute))).Description;// 属性描述值

                        //注意:文本域名称 == 模型中属性的 Description 值 !!!!!!
                        //也可以: 文本域名称 == 模型中属性的 Name 值 !!!!!!
                        if (field.Name == des)
                        {
                            if (field.DocumentObjectType == DocumentObjectType.TextFormField)   //文本域
                            {
                                if (prop.PropertyType.Name == "Boolean")
                                {
                                    field.Text = "√";   //插入勾选符号
                                    break;
                                }
                                else
                                {
                                    field.Text = value.ToString();   //向Word模板中插入值
                                    break;
                                }
                            }
                            else if (field.DocumentObjectType == DocumentObjectType.CheckBox)   //复选框
                            {
                                (field as CheckBoxFormField).Checked = (value as bool?).HasValue ? (value as bool?).Value : false;
                            }
                        }
                    }
                }

                doc.SaveToFile(ExpFilePath, FileFormat.Docx);
                doc.Close();

                return true;
            }
            catch (Exception ex)
            {
                string msg = ex.Message;

                return false;
            }
        }
    }
}

基本功能已经实现,还有待改进,希望各位提出宝贵意见!

(PS:如果有朋友知道NPOI如何实现类似功能的,望告知下!先谢谢了!^_^)

相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: