C# 解决Excel边框样式无法复制问题及实现格式刷功能

news2024/11/6 3:17:10

 

目录

问题现象

范例运行环境

解决方案

剪贴板加特殊粘贴

自定义样式

直接赋值

完美方案 

小结


问题现象

在运行数据表数据导出到 EXCEL 数据输出时遇到了一个问题,开发者设计了单行细线下边框的输出模板,如下图设计:

其中 <%system.excel.title.dyna.by.craneoffice%> 字符标记用于输出报表标题替换。数据从A5列开始至D5列结束,按行输出。期望得到如下输出样式:

虽然已经自定义了复制样式的方法,包括边框风格的复制,但实际输出遇到了如下情况:

实际想要得到的单行细线下边框输出没有实现,使用简单 Borders.LineStyle 赋值没有奏效,以后输出的行复制第一行的样式没有成功,因此需要调整样式输出策略,实现类似格式刷那样的操作,这样即实现了格式输出的完整性,也保证了性能。

范例运行环境

操作系统: Windows Server 2019 DataCenter

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

Office Excel 2016

开发工具:VS2019  C# 

解决方案

剪贴板加特殊粘贴

使用 COM 操作的流程原理如下图:

实现代码,示例如下:

SRange.Copy();  //将源选定范围复制到剪贴板   
Range.PasteSpecial(Excel.XlPasteType.xlPasteFormats);  //特殊粘贴格式到目标选定范围

Copy() 方法实现了复制所有数据到剪贴板功能,其中也包括了样式。 PasteSpecial() 方法实现了指定粘贴的功能,其中 Excel.XlPasteType.xlPasteFormats 表示只粘贴格式样式,至此实现了模拟格式刷的功能。 但此方法可能会引起多 Excel 应用的复制冲突,因此相对保险的写法可以改成如下代码:

SRange.Copy(Range);

但这样会有一个问题是,如果像模板输出还好,但想要仅粘贴格式则无法实现,因此也有局限性。而且这种实现原理,微软可能也会有所调整,也无法保障以后的应用是否会引起复制冲突。所以我们在下个小节通过自定义样式的方式来模拟格式刷的功能。

自定义样式

使用 COM 操作的流程原理如下图:

示例代码如下:

string stylename = Guid.NewGuid().ToString();
WorkBook xb=WorkBooks[1];

Style newStyle = xb.Styles.Add(stylename);

 设置样式属性
newStyle.Font.Name = "宋体";
newStyle.Font.Size = 11;
newStyle.Font.Bold = true;

newStyle.Borders.Weight = XlBorderWeight.xlHairline;  //最细的线
newStyle.Borders.LineStyle = XlLineStyle.xlContinuous;  //实线

以上是添加样式的示例,因为样式很多,实现格式复制的简单方法,是创建新名称并直接引用源单元格的样式,应用到目标选范围上即可,如果有需要移除或修改的样式,可以继续对新建样式进行赋值,修改后如下代码示例:

string stylename = Guid.NewGuid().ToString();
WorkBook xb=WorkBooks[1];

Style newStyle = xb.Styles.Add(stylename);

newStyle = SRange.Style;  //将源选定范围样式赋值到自定义新建样式

newStyle.Font.Name="宋体"; //修改字体为宋体

Range.Style = newStyle.Name;

直接赋值

Range.Style 是一个 dynamic 类型,可以赋予任何可以正确实现的类型,如自定义样式名称(newStyle.Name),也可以直接赋值为 Style 类型,简单而暴力,代码如下:


Range.Style = SRange.Style;  //将源选定范围样式赋值到目标

完美方案 

在实际的运行中,无论是自定义样式还是直接赋值模式,对复制字体时出现了无法复制的问题,因此还是需要结合自定义复制样式方法来弥补问题,代码如下:

public void copyRangeStyle(Excel.Range srcRange,Excel.Range desRange)
{

	desRange.Font.Background=srcRange.Font.Background;
	desRange.Font.Bold=srcRange.Font.Bold;
	desRange.Font.Color=srcRange.Font.Color;
	desRange.Font.Italic=srcRange.Font.Italic;
	desRange.Font.Name=srcRange.Font.Name;
	desRange.Font.OutlineFont=srcRange.Font.OutlineFont;
	desRange.Font.Shadow=srcRange.Font.Shadow;
	desRange.Font.Size=srcRange.Font.Size;
	desRange.Font.Strikethrough=srcRange.Font.Strikethrough;
	desRange.Font.Underline=srcRange.Font.Underline;

	desRange.RowHeight=srcRange.RowHeight;


    desRange.HorizontalAlignment=srcRange.HorizontalAlignment;
	desRange.VerticalAlignment=srcRange.VerticalAlignment;
}

 copyRangeStyle 自定义复制样式方法包括 源选定范围参数(Excel.Range srcRange)和目标选定范围参数(Excel.Range desRange),至此,完整代码可修整如下:

Range.Style = SRange.Style;

copyRangeStyle(SRange, Range);

至此结合  copyRangeStyle 方法完美解决样式复制问题。

copyRangeStyle 方法请根据实际需要的样式进行扩充或调整。

小结

关于 Range.Borders 的COM 操作如下图:

这个样式的设定是有点击顺序的,选边框后点击样式是无效的,需要点击样式再进行选边框的切换,才会得到预期效果。正常可通过 Range.Borders 直接表示所有6个框线的集合,直接为其赋值,如下代码:

newStyle.Borders.Weight = XlBorderWeight.xlHairline;  //最细的线
newStyle.Borders.LineStyle = XlLineStyle.xlContinuous;  //实线类型边框
newStyle.Borders.Color = Color.Red;  //红色边框

如果想只设置某一边框,则需要获取 Borders 集合里的 Border,如下几种方式都可以获取其中的某一个 Border 对象:


//右、左、下、上边框
Range.Borders.get_Item(XlBordersIndex.xlEdgeRight).LineStyle = XlLineStyle.xlLineStyleNone;
Range.Borders.get_Item(XlBordersIndex.xlEdgeLeft).LineStyle = XlLineStyle.xlContinuous;
Range.Borders.get_Item(XlBordersIndex.xlEdgeBottom).LineStyle = XlLineStyle.xlContinuous;
Range.Borders.get_Item(XlBordersIndex.xlEdgeTop).LineStyle = XlLineStyle.xlContinuous;

//内部交叉斜线
Range.Borders.Item[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone;
Range.Borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;

我们可以使用 Borders.get_Item 方法或引用 Item 索引或直接引用索引的方法得到 Border,但实际的使用过程中,预期效果不理想,因此我们使用了样式赋值,类似格式刷的方法来解决。 

更多可参考如下文章链接:

https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.office.interop.excel.xlbordersindex?view=excel-pia&source=recommendations

https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.office.interop.excel.styles?view=excel-pia

《C# 实现二维数据数组导出到 Excel》

本文代码仅供您参考使用,感谢您的阅读,希望本文能够对您有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2181557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习篇-day02-KNN算法实现鸢尾花模型和手写数字识别模型

一. KNN简介 KNN思想 K-近邻算法&#xff08;K Nearest Neighbor&#xff0c;简称KNN&#xff09;。比如&#xff1a;根据你的“邻居”来推断出你的类别 KNN算法思想&#xff1a;如果一个样本在特征空间中的k 个最相似的样本中的大多数属于某一个类别&#xff0c;则该样本也属…

sentinelhub3.7相比3.4的版本主要变化

sentinelhub3.7相比3.4的版本&#xff0c;主要变化包括: 1. 增加对sentinel 基线04.00数据产品的支持&#xff1b; 2. 将aws数据下载模块独立出来 3.4版本 3.7版本 3. 原来的DataSource改为DataCollection 3.7版本不再支持DataSource 3.4版本中的DataSource 3.7版本使用Data…

鸿蒙NEXT入门到实战(基于最新api12稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

音频信号处理学习

来源B站&#xff0c;但是代码微改&#xff0c;更好理解。 B站网址&#xff1a;https://www.bilibili.com/video/BV1vT411m7yc/?spm_id_from333.788&vd_sourcec105ef445d9ba79ff025b5ba5869ce2b import mathimport librosa import numpy as np import matplotlib.pyplot a…

【floor报错注入】

一、sql语句基础 floor 向下取整 count 取数据的数量 group by 分组查询 Rand 随机数 limit 二、floor报错注入 主键重复报错 我们先了解group by产生的虚拟表的原理&#xff0c;了解到虚拟表的主键是不可以重复的 我们再可以通过Rand(0)函数规定固定种子后乘2&…

Jmeter常用函数、逻辑控制器

目录 一、Jmeter常用函数 counter函数 machineName函数 machineIP函数 Random函数 RandomString函数 RandomDate函数 time函数 二、逻辑控制器 IF控制器 循环控制器 foreach控制器 仅一次控制器 事务控制器 聚合报告 随机控制器 随机顺序控制器 一、Jmeter常用…

Webpack 打包后文件过大,如何优化?

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介Webpack 打包后文件过大&#xff0c;如何优化&#xff1f;1. 代码分割&#xff08;Code Splitting&#xff09;1.1 概念1.2 Webpack 的 SplitChunksPlugin示例配置&#xff1a; 1.3 按需加载&#xff08;Lazy Loading&#xff09;示…

位运算(1)_常见位运算总结

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 位运算(1)_常见位运算总结 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 基…

综合练习 学习案例

//验证码 前四位是字母 最后一位是数字 public class test1 {public static void main(String[] args){char [] charsnew char[52];for (int i 0; i <chars.length ; i) {if(i<25){chars[i](char)(i97);}else{chars[i](char)(i65-26);}}Random rnew Random();String cod…

虚商目前有哪些业务痛点?

虚拟运营商当前面临的业务痛点主要集中在市场竞争、运营成本、技术依赖、用户体验及政策监管等方面。 一、市场竞争激烈 1、竞争者数量增加: 随着市场准入门槛的降低&#xff0c;越来越多的企业进入虚拟运营商市场导致市场竟争日益激烈。为了争夺市场份额&#xff0c;企业不得不…

高校体育场小程序|高校体育场管理系统系统|体育场管理系统小程序设计与实现(源码+数据库+文档)

高校体育场管理系统小程序 目录 体育场管理系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道…

量化必备!股票常用数据批量下载、定时更新,代码打包好了!

上一节课我详细演示了从tushare获取股票列表和基本信息并且配置定时更新任务的详细流程&#xff0c;旨在教会想要学习通过Python获取股票数据并且定期更新的朋友。 不过有很多朋友完全没有Python基础&#xff0c;如果一开始把大量时间花费在搞数据上&#xff0c;本末倒置不说&…

学MybatisPlus

1.设置MySql的数据库 spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicodetrue&characterEncodingUTF-8&autoReconnecttrue&serverTimezoneAsia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: MySQL123 logging:l…

GIT安装及集成到IDEA中操作步骤

最近深感GIT使用技能太差&#xff0c;我只会些皮毛&#xff0c;还是得看官网&#xff0c;总结一下常用的操作方法吧。 GIT环境配置到IDEA中安装 一、GIt的基本的安装 这个不在这里赘述了&#xff0c;自己装一个git吧 二、给IDEA指定本地GIT的安装路径 1、下图这个是我本地的…

计算机毕业设计hadoop+spark+hive视频推荐系统 视频情感分析可视化 视频爬虫 视频爬虫 知识图谱 大数据毕设

《HadoopSparkHive视频推荐系统》开题报告 一、引言 随着互联网技术的飞速发展&#xff0c;视频内容呈现出爆炸式增长&#xff0c;用户面临着从海量视频资源中快速找到感兴趣内容的挑战。传统的视频推荐系统已难以满足大规模数据处理的需求&#xff0c;因此&#xff0c;基于H…

迁移学习案例-python代码

大白话 迁移学习就是用不太相同但又有一些联系的A和B数据&#xff0c;训练同一个网络。比如&#xff0c;先用A数据训练一下网络&#xff0c;然后再用B数据训练一下网络&#xff0c;那么就说最后的模型是从A迁移到B的。 迁移学习的具体形式是多种多样的&#xff0c;比如先用A训练…

仿真设计|基于51单片机的智能防火GSM上报仿真

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602显示实时温度&#xff08;DS18B20&#xff09;值和烟雾&#x…

避免学术欺诈!在ChatGPT帮助下实现严格引用并避免抄袭

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 当今的学术环境中&#xff0c;保持学术诚信至关重要。随着ChatGPT等技术的发展&#xff0c;写作变得更加高效&#xff0c;但也增加了不当使用的风险。严格的引用和避免抄袭不仅是学术道…

一个服务器可以搭建几个网站

一个服务器可以搭建几个网站 该省就得省&#xff0c;一台服务器可以搭建多种不同的网站或应用#服务器#服务器租用 多个站点放在同一个服务器上有什么影响吗&#xff1f; 服务器里面会涉及到就是内存和带宽&#xff0c;如果说你一个服务器只放一个网站肯定更好一点&#xff0…

java将word转pdf

总结 建议使用aspose-words转pdf,poi的容易出问题还丑… poi的(多行的下边框就不对了) aspose-words的(基本和word一样) poi工具转换 <!-- 处理PDF --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres…