当前位置: 首页 > news >正文

C# 读取多条数据记录导出到 Word标签模板之图片输出改造

目录

应用需求

设计

范例运行环境

配置Office DCOM

实现代码

组件库引入

​核心代码

调用示例

小结


应用需求

在我的文章《C# 读取多条数据记录导出到 Word 标签模板》里,讲述读取多条数据记录结合 WORD 标签模板输出文件的功能,原有输出图片的约定是在 WORD 模板文件中借助书签设置进行输出,如下图:

该书签名称代表了一条指令,格式为(输出关键字_图片宽度_图片高度)。如图中书签名称设置,当系统遇到 ds_qz 关键字时,输出按后继设置进行,图片宽度为100、图片高度为 50。

现有一模板需求如下图:

我们需要在考官评语和考官本人签字位置输出手写图片,原有的书签模式输出会遇到一些问题:

(1)只能为嵌入式,位置输出无法设置,无法进一步调整到较优呈现位置。

(2)只能插入式输出,无法实现嵌入式如文字浮动、环绕效果。

(3)需要在无关位置插入书签,否则会在输出关键字时被替换掉,而无法识别配置。

(4)书签的名称不能输入一些特定字符,如%,减号等,给配置带来一些麻烦。

(5)如果在文档里真需要设置书签,容易造成混乱。

设计

设计提供一个 ArrayList 类型参数取代书签模式的设计,其格式为 (输出关键字_图片宽度_图片高度_图片 Left 相对值_图片 Top 相对值 )。如添加 ds_qz_100_50_500_-20 字符串,当系统遇到 ds_qz 关键字时,输出按后继设置进行,图片宽度为100、图片高度为 50、图片 Left 为500、图片 Top 为 -20。后四个参数如果设置null则表示忽略,ds_qz_null_null_500_-20 ,则表示忽略宽度和高度设置,即表示原始大小输出。

定位到的图片输出,采取浮动于文字下方的处理。

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Word 2016

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.7.2 或以上

开发工具:VS2019  C#

配置Office DCOM

配置方法可参照我的文章《C# 读取Word表格到DataSet》进行处理和配置。

实现代码

组件库引入

核心代码

public string DataTableToWord(string _filename,string _repeatKey,object _dataset,ArrayList DataSetPictureConfig),该方法提供4个参数,WORD模板文件名、自定义关键字、System.Data.DataSet,配置图片用的 ArrayList 列表指令。

public void DataTableToWord(string _filename,string _repeatKey,object _dataset,ArrayList DataSetPictureConfig){if (DataSetPictureConfig == null) { DataSetPictureConfig = new ArrayList(); }Object Nothing = System.Reflection.Missing.Value;object filename = _filename;//创建一个名为WordApp的组件对象Word.Application WordApp = new Word.Application();//创建一个名为WordDoc的文档对象WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;Word.Document WordDoc = WordApp.Documents.Open(ref filename, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);WordDoc.SpellingChecked = false;//关闭拼写检查WordDoc.ShowSpellingErrors = false;//关闭显示拼写错误提示框WordApp.Selection.WholeStory();WordApp.Selection.Cut();DataSet ds=(DataSet)_dataset;System.Data.DataTable  dt=ds.Tables[0];for(int i=0;i<dt.Rows.Count;i++){WordApp.Selection.Paste();for(int j=0;j<dt.Columns.Count;j++){string _repKey=_repeatKey+dt.Columns[j].ColumnName.ToString();string _repValue=string.Format("{0}",dt.Rows[i][j].ToString());bool isPhoto=false;if(dt.Columns[j].DataType==typeof(System.Byte[])){isPhoto=true;_repValue="";}WordApp.Options.ReplaceSelection=true;Word.Find fnd = WordApp.Selection.Find;fnd.ClearFormatting();Object findText = _repKey;Object matchCase = false;Object matchWholeWord = Type.Missing;Object matchWildcards = false;Object matchSoundsLike = false;Object matchAllWordForms = false;Object forward = true;Object wrap =Word.WdFindWrap.wdFindContinue;Object format = false;Object replaceWith ="";Object replace =Type.Missing;;Object matchKashida = Type.Missing;Object matchDiacritics = Type.Missing;Object matchAlefHamza = Type.Missing;Object matchControl = Type.Missing;while(fnd.Execute(ref findText, ref matchCase, ref matchWholeWord,ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWith,ref replace, ref matchKashida, ref matchDiacritics,ref matchAlefHamza, ref matchControl)){string r_f=WordApp.Selection.Font.Name.ToString();WordApp.Selection.Range.Text=_repValue;if(isPhoto==true){string _jpgfile=_path+System.Guid.NewGuid()+".jpg";if (dt.Rows[i][j] == System.DBNull.Value){continue;}byte[] filedata = (byte[])dt.Rows[i][j];System.IO.MemoryStream ms = new MemoryStream(filedata);System.Drawing.Image img1 = System.Drawing.Image.FromStream(ms);img1.Save(@_jpgfile);ms.Close();Word.InlineShape pic= WordApp.Selection.InlineShapes.AddPicture(@_jpgfile,false,true);foreach (string bm in  DataSetPictureConfig){string _findkey=_repKey+"_";int _f1 =bm.IndexOf(_findkey);if(_f1==0 && bm.Length>(_findkey.Length)){string[] _paras=bm.Substring(_findkey.Length,bm.Length-_findkey.Length).Split('_');if(_paras.GetLength(0)>1){if (_paras[0] != "null"){int def_width = int.Parse(_paras[0]);pic.Width = def_width;}if (_paras[1] != "null"){int def_height = int.Parse(_paras[1]);pic.Height = def_height;}}}}Word.Shape pic2 = pic.ConvertToShape();pic2.WrapFormat.Type = Word.WdWrapType.wdWrapThrough;pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind;pic2.Left = 0;pic2.Top = 0;foreach (string bm in DataSetPictureConfig){string _findkey = _repKey + "_";int _f1 = bm.IndexOf(_findkey);if (_f1 == 0 && bm.Length > (_findkey.Length)){string[] _paras = bm.Substring(_findkey.Length, bm.Length - _findkey.Length).Split('_');if (_paras.GetLength(0) > 3){if (_paras[2] != "null")pic2.Left = float.Parse(_paras[2]);if (_paras[3] != "null")pic2.Top =float.Parse(_paras[3]);}}}File.Delete(@_jpgfile);}}}object dummy = System.Reflection.Missing.Value;object what = Word.WdGoToItem.wdGoToLine;object which = Word.WdGoToDirection.wdGoToLast;object count = System.Reflection.Missing.Value;
//					WordApp.Selection.GoTo(ref oGoToItem, ref oGoToLast, ref Nothing, ref Nothing);WordApp.Selection.GoTo(ref what, ref which, ref count, ref dummy);//default 表示每行记录之间插入分页符,最后一行时不再插入分页符,以免造成多余一空白页if(i!=dt.Rows.Count-1){object ib = Word.WdBreakType.wdPageBreak; WordApp.Selection.InsertBreak(ref ib);}}}WordDoc.Save();WordDoc.Close(ref Nothing, ref Nothing, ref Nothing);//关闭WordApp组件对象WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);}

调用示例

示例代码如下:

DataSet rv = GetDataSet("select * from tabble");ArrayList picconfig = new ArrayList();   //可配置每个图片字段的大小及位置
picconfig.Add("ds_kg_sign_100_50_500_-20");   //格式为: key_width_height_left_top
string ModuleFile = "d:\\bfile\\word\\面试评分表.docx";  //假设的模板文件
string _lastfile = DataTableToWord(ModuleFile,"ds_",ds,picconfig);MessageBox.Show(string.Format("已成功导出文件:{0}", _lastfile));

运行结果预览如下图:

 

小结

核心代码中需要将 Word.InlineShape 转换为 Word.Shape 后,可以进行环绕文字的操作,如下:

Word.Shape pic2 = pic.ConvertToShape();
pic2.WrapFormat.Type = Word.WdWrapType.wdWrapThrough;
pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind;
pic2.Left = 0;
pic2.Top = 0;

使用 ConvertToShape() 方法转换为 pic2 , pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind;  可以浮动于文字下方,然后初始图片的 Left 和 Top ,否则有可能无法正常显示位置。

我们可以根据自己的实际情况设置环绕格式,可参阅读如下地址:

https://learn.microsoft.com/zh-cn/office/vba/api/word.wdwraptypemerged

这些代码我们提供了一些操作WORD相关的关键方法,这里仅作参考,欢迎大家评论指教!

相关文章:

C# 读取多条数据记录导出到 Word标签模板之图片输出改造

目录 应用需求 设计 范例运行环境 配置Office DCOM 实现代码 组件库引入 ​核心代码 调用示例 小结 应用需求 在我的文章《C# 读取多条数据记录导出到 Word 标签模板》里&#xff0c;讲述读取多条数据记录结合 WORD 标签模板输出文件的功能&#xff0c;原有输出图片的…...

NSSCTF web刷题

1 虽然找到了flag,但是我要怎么去改他的代码,让他直接输出flag呢? (好像是要得到他的json代码,这题不让看) 2 wllm应该就是他的密码,进入许可了 意思是服务器可以执行通过POST的请求方式传入参数为wllm的命令&#xff0c;那这就是典型的命令执行&#xff0c;当然&#xff0c…...

对象排序得到方式

java实现 list 排序的方式&#xff0c;有三种 ① 对象实现Comparable 接口&#xff0c;然后代码里直接调用Collections.sort(list) ②使用内部类Comparator ③使用stream.sort 代码如下 实现Comparable接口的实体类 Data public class Student implements Comparable<Stud…...

Day2 洛谷1035+1047+1085+1089+1150+1151

零基础洛谷刷题记录 Day1 2024.11.18 Day2 2024.11.25 文章目录 零基础洛谷刷题记录1035:题目描述1035&#xff1a;解答代码1035&#xff1a;学习成果1047&#xff1a;题目描述&#xff08;成功写出&#xff09;1047&#xff1a;解答代码1047&#xff1a;学习成果1085&#xf…...

Linux:进程间通信之进程池和日志

一、进程池的设计 因为每一次我们要进行进程间通信都需要fork&#xff0c;和操作系统做交互是存在很大成本的&#xff0c;所以我们是不是可以提前fork出几个进程&#xff0c;然后当我们想要使用的时候直接去给他们安排任务&#xff0c;这样就减少了系统调用的次数从而提高了内存…...

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…...

Paddle Inference部署推理(十二)

十二&#xff1a;Paddle Inference推理 &#xff08;python&#xff09;API详解 15. PredictorPool 类 PredictorPool 对 Predictor 进行了简单的封装&#xff0c;通过传入 config 和 thread 的数目来完成初始化&#xff0c;在每个线程中&#xff0c;根据自己的线程 id 直接从…...

外观模式 (Facade Pattern)

外观模式 (Facade Pattern) 外观模式是一种 结构型设计模式&#xff0c;通过为子系统中的一组接口提供一个统一的高层接口&#xff0c;简化了子系统的使用&#xff0c;让复杂系统更易于访问。 原理 核心思想&#xff1a; 提供一个 统一的接口 来访问子系统中的多个接口&#…...

人工智能-深度学习-Torch框架-手动构建回归流程

from sklearn.datasets import make_regression import math import random import torch from sklearn.datasets import make_regression: 导入make_regression函数&#xff0c;用于生成回归数据集。 import math: 导入math模块&#xff0c;用于进行数学计算&#xff0c;例如…...

SpringBoot源码解析(五):准备应用环境

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…...

MySQL面试-1

InnoDB中ACID的实现 先说一下原子性是怎么实现的。 事务要么失败&#xff0c;要么成功&#xff0c;不能做一半。聪明的InnoDB&#xff0c;在干活儿之前&#xff0c;先将要做的事情记录到一个叫undo log的日志文件中&#xff0c;如果失败了或者主动rollback&#xff0c;就可以通…...

nginx配置不缓存资源

方法1 location / {index index.html index.htm;add_header Cache-Control no-cache,no-store;try_files $uri $uri/ /index.html;#include mime.types;if ($request_filename ~* .*\.(htm|html)$) {add_header Cache-Control "private, no-store, no-cache, must-revali…...

PHP导出EXCEL含合计行,设置单元格格式

PHP导出EXCEL含合计行&#xff0c;设置单元格格式&#xff0c;水平居中 垂直居中 public function exportSalary(Request $request){//水平居中 垂直居中$styleArray [alignment > [horizontal > Alignment::HORIZONTAL_CENTER,vertical > Alignment::VERTICAL_CE…...

RabbitMQ 之 死信队列

一、死信的概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息进行…...

【创建型设计模式】单例模式

【创建型设计模式】单例模式 这篇博客接下来几篇都将阐述设计模式相关内容。 接下来的顺序大概是&#xff1a;单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 一、什么是单例模式 单例模式是一种创建型设计模式&#xff0c;它保证一个类仅有一个实例&#…...

Charles抓包工具-笔记

摘要 概念&#xff1a; Charles是一款基于 HTTP 协议的代理服务器&#xff0c;通过成为电脑或者浏览器的代理&#xff0c;然后截取请求和请求结果来达到分析抓包的目的。 功能&#xff1a; Charles 是一个功能全面的抓包工具&#xff0c;适用于各种网络调试和优化场景。 它…...

Go语言使用 kafka-go 消费 Kafka 消息教程

Go语言使用 kafka-go 消费 Kafka 消息教程 在这篇教程中&#xff0c;我们将介绍如何使用 kafka-go 库来消费 Kafka 消息&#xff0c;并重点讲解 FetchMessage 和 ReadMessage 的区别&#xff0c;以及它们各自适用的场景。通过这篇教程&#xff0c;你将了解如何有效地使用 kafk…...

【论文笔记】Number it: Temporal Grounding Videos like Flipping Manga

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Number it: Temporal Grou…...

C语言菜鸟入门·关键字·int的用法

目录 1. int关键字 1.1 取值范围 1.2 符号类型 1.3 运算 1.3.1 加法运算() 1.3.2 减法运算(-) 1.3.3 乘法运算(*) 1.3.4 除法运算(/) 1.3.5 取余运算(%) 1.3.6 自增()与自减(--) 1.3.7 位运算 2. 更多关键字 1. int关键字 int 是一个关键字&#xff0…...

基于企业微信客户端设计一个文件下载与预览系统

在企业内部沟通与协作中&#xff0c;文件分享和管理是不可或缺的一部分。企业微信&#xff08;WeCom&#xff09;作为一款广泛应用于企业的沟通工具&#xff0c;提供了丰富的API接口和功能&#xff0c;帮助企业进行高效的团队协作。然而&#xff0c;随着文件交换和协作的日益增…...

昇思MindSpore第七课---文本解码原理

1. 文本解码原理 文本解码是将模型的输出&#xff08;通常是概率分布或词汇索引&#xff09;转换为可读的自然语言文本的过程。在生成文本时&#xff0c;常见的解码方法包括贪心解码、束搜索&#xff08;BeamSearch&#xff09;、随机采样等。 2 实践 2.1 配置环境 安装mindn…...

C# 数据结构之【图】C#图

1. 图的概念 图是一种重要的数据结构&#xff0c;用于表示节点&#xff08;顶点&#xff09;之间的关系。图由一组顶点和连接这些顶点的边组成。图可以是有向的&#xff08;边有方向&#xff09;或无向的&#xff08;边没有方向&#xff09;&#xff0c;可以是加权的&#xff…...

传输控制协议(TCP)和用户数据报协议(UDP)

一、传输控制协议&#xff08;TCP&#xff09; 传输控制协议&#xff08;Transmission Control Protocol&#xff0c;TCP&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由 IETF 的 RFC 793 定义。 它通过三次握手建立连接&#xff0c;确保数…...

【Python爬虫】Scrapy框架实战---百度首页热榜新闻

如何利用Scrapy框架实战提取百度首页热榜新闻的排名、标题和链接 一、安装Scrapy库 二、创建项目&#xff08;以BaiduSpider为例&#xff09; scrapy startproject BaiduSpider生成每个文件的功能&#xff1a; 二、 创建爬虫脚本&#xff08;爬虫名&#xff1a;news&#xff…...

采用python3.12 +django5.1 结合 RabbitMQ 和发送邮件功能,实现一个简单的告警系统 前后端分离 vue-element

一、开发环境搭建和配置 #mac环境 brew install python3.12 python3.12 --version python3.12 -m pip install --upgrade pip python3.12 -m pip install Django5.1 python3.12 -m django --version #用于检索系统信息和进程管理 python3.12 -m pip install psutil #集成 pika…...

Qt 实现网络数据报文大小端数据的收发

1.大小端数据简介 大小端&#xff08;Endianness&#xff09;是计算机体系结构的一个术语&#xff0c;它描述了多字节数据在内存中的存储顺序。以下是大小端的定义和它们的特点&#xff1a; 大端&#xff08;Big-Endian&#xff09; 在大端模式中&#xff0c;一个字的最高有效…...

[译]Elasticsearch Sequence ID实现思路及用途

原文地址:https://www.elastic.co/blog/elasticsearch-sequence-ids-6-0 如果 几年前&#xff0c;在Elastic&#xff0c;我们问自己一个"如果"问题&#xff0c;我们知道这将带来有趣的见解&#xff1a; "如果我们在Elasticsearch中对索引操作进行全面排序会怎样…...

Java基于SpringBoot+Vue的藏区特产销售平台

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

12-表的约束

知识背景 表的约束&#xff0c;就是在表中的数据上加上约束&#xff0c;也被称为数据完整性约束。数据完整性约束的目的是为了不被规定的、不符合规范的数据进入数据库 在录入数据库或数据发生变化时&#xff0c;DBMS(数据库管理系统)会按照一定的约束条件对数据进行监测&…...

【人工智能】深度学习入门:用TensorFlow实现多层感知器(MLP)模型

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 多层感知器(MLP)是一种基础的神经网络结构,广泛应用于分类和回归任务。作为深度学习的重要组成部分,理解并实现MLP是学习更复杂神经网络模型的基础。本文将介绍多层感知器的核心概念、数学原理,并使用…...