C# 实现格式化文本导入到Excel

目录

需求

Excel 的文本文件导入功能

范例运行环境

配置Office DCOM

实现

组件库引入

OpenTextToExcelFile

代码

调用

小结


需求

在一些导入功能里,甲方经常会给我们一些格式化的文本,类似 CSV 那样的纯文本。比如有关质量监督的标准文件(如国家标准、地方标准、企业标准等),还有一此国际标准文件等等。提供给我们的这些文件是文件尺寸比较大的纯文本文件,文件内容是格式化的文本,具有规律的分隔字符。Excel 本身提供有导入文本文件的功能,但由于标准制定和发布是比较频繁,每次的导入与整理还是比较耗时的,因些实现文本文件导入到 Excel 的功能可以更快速的解决重复劳动和错误,实现流程自动化的一环。

Excel 的文本文件导入功能

我们运行 Excel ,点击选择打开文本文件时,会弹出一个导入向导,如下图:

 

 

如图我们需要选择合适的文本文件原始编码,输入分隔符,选择其它的选项,如连续的分隔符号视分单个处理等。下面我们将介绍如何利用 COM 来实现这一操作的自动化处理。 

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Excel 2016

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

开发工具:VS2019  C#

配置Office DCOM

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

实现

组件库引入

OpenTextToExcelFile

OpenTextToExcelFile方法返回 object[] 类型,object[0] 返回生成成功的 Excel 文件地址,object[1]返回错误信息,其实体为 string 类型。方法参数据说明见下表:

序号参数类型说明
1OpenFilestring打开的文本文件的绝对完整路径及名称。
2ExcelFilestring要生成的Excel文件完整路径地址。
3SplitCharstring分隔符
4ReplaceCharsstring[,]这是一个导入后数据整理型参数。一个二维数组,用于导入后替换相关字符的数组,第一维为查找字符串  ,第二维为要替换的字符串。
5ValidResultint这是一个检验型参数。指定有效的字段生成数,如果小于1则不进行判断,否则如果生成的最终列数与此值不符,则生成错误信息以示警告。
6ExtraSplitbool是否允许删除指定的一系列列值。
7Esplitsint[]当ExtraSplit为true时,些数据生效,如定义1、6、19列等。这些列的值将在Esplits参数数组中定义。Esplits数组的指定生效顺序在StartCol参数之后
8AddColsobject[,]

这是一个整理型参数。表示要添加几个固定列及固定值,维度包括3列,如object[0,0] 存储要写入的列id,object[0,1] 存储列id的标题值,object[0,2] 存储列id的值。示例如下:

object[0,0]=10;

object[0,1]="导入标志";

object[0,2]="是";  

9ref_maxcolidint指定在打开文本文件之后应该生成的最大的列,一般这个参数用于最后一列都为空的情况,因为这样EXCEL无法定位最后一个单元格,如果为0则忽略
10StartColint这是一个整理型参数。指定额外的删除列策略,默认值为1,表示不处理,<=0 则表示删除前几列。即 Math.Abs(StartCol) 个,默认步长为 1。
11offersetint与StartCol参数配合,默认值为1,表示删除步长。注意:改变此值会影响删除列的个数。
12originint文本文件的原始编码,默认为 65001,即UTF-8
13ConsecutiveDelimiterbool如果为 true,则将连续分隔符视为一个分隔符,如“##” 则视为“#”。 默认值为 false。

代码

方法完整代码如下:

/*本方法通过打开一个具有一定分隔格式的文本到EXCEL中,并且由EXCEL进行整理* openfile参数:打开的文件绝对完整路径及名称。splitchar参数:分隔符。ReplaceChars参数:一个二维数组,用于整理后替换相关字符的数组,第一维为查找字符串* ,第二维为要替换的字符串。allowtodataset参数:是否允许整理后生成一个dataset对象。ValidResult参数:指定有效的字段生成数,如果小于1则不进行判断,否则如果* 生成的最终列数与此值不符,则生成错误信息。StartCol参数:指定额外的分隔列策略,大于0为不处理。小于1则表示以最大列加上此值为基准行进行倒序删除,* 删除位移为offerset参数指定的数值。ExtraSplit参数:是否指定一系列列值进行删除,这些列可能是无规律的,如1、6、19列等。这些列的值将在Esplits参数数组中定义* 注意Esplits数组的指定生效顺序在StartCol参数之后,如果StartCol参数有效的话。obj_table参数:是否有目标参照表SQL语句返回的结果与文本列进行对应* XmlCfg 文件,如果您有XML配置文件,则可以忽略除openfile以外所有的参数传递,本函数将分析此配置文件的内容,如果分析失败则整个函数将失败*ref_maxcolid,由用户指定在打开文本文件之后应该生成的最大的列,一般这个参数用于最后一列都为空的情况,因为这样EXCEL无法定位最后一个单元格,如果为0则跳过
*/
public object[] OpenTextToExcelFile(string OpenFile, string SplitChar, string[,] ReplaceChars, int ValidResult, bool ExtraSplit, int[] Esplits, object[,] AddCols, int ref_maxcolid, int StartCol = 1, int offerset = 1)
{object[] rv = new object[4];rv[0] = ""; //存储返回生成的EXCEL文件rv[1] = ""; //返回错误信息或附加的信息rv[2] = null;rv[3] = "";try{//创建EXCEL应用对象ExcelApplication excel = new ExcelApplication();Workbooks workbook = excel.Workbooks;object[,] dlist = new object[ref_maxcolid, 2];for (int i = 0; i < ref_maxcolid; i++){dlist[i, 0] = i + 1;dlist[i, 1] = Excel.XlColumnDataType.xlTextFormat;}workbook.OpenText(OpenFile, 20936, 1, Excel.XlTextParsingType.xlDelimited,Excel.XlTextQualifier.xlTextQualifierDoubleQuote, false, false, false, false, false, true, SplitChar,dlist,Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);Excel.Range _range;int maxcolid = excel.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Column;if (ref_maxcolid > 0){maxcolid = ref_maxcolid;}int maxrowid = excel.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Row;int _addcol = 0;if (AddCols != null){_addcol = AddCols.GetLength(0);}int delcount = 0;if (StartCol <= 0){for (int i = (maxcolid + StartCol); i >= 1; i -= offerset){_range = excel.get_Range(excel.Cells[1, i], excel.Cells[65536, i]);_range.Select();_range.Delete(Type.Missing);delcount++;}}if ((ExtraSplit) && (Esplits != null)){for (int j = 0; j < Esplits.GetLength(0); j++){int colid = Esplits[j];_range = excel.get_Range(excel.Cells[1, colid], excel.Cells[65536, colid]);_range.Select();_range.Delete(Type.Missing);delcount++;}}if ((ValidResult > 0) && ((maxcolid - delcount + _addcol) != ValidResult)){rv[1] = "生成的最终数据结果与指定的列数目不符合。\r\n用户指定的有效列为:" +ValidResult.ToString() + "\r\n系统生成的列:" + (maxcolid - delcount).ToString() + "附加的列:" + _addcol.ToString() +"\r\n系统检测到的最大列:" + maxcolid.ToString(); //返回错误信息return rv;}//创建模板的映像解析文件,最终以变量 desfilename 为输出对象FileEx commonApi = new FileEx();string _file = "", _path = "";_path = Path.GetDirectoryName(OpenFile);if (_path.Length > 3){_path += "\\";}_file = Path.GetFileNameWithoutExtension(OpenFile);string _validfilename = commonApi.GetValidFileName(_path, _file, ".xlsx");string _lastfile = _path + _validfilename;rv[0] = _lastfile;if (File.Exists(_lastfile)){File.Delete(_lastfile);}Worksheet worksheet = (Worksheet)excel.ActiveSheet;//解决替换字符的要求if (ReplaceChars != null){for (int i = 0; i < ReplaceChars.GetLength(0); i++){string _find = ReplaceChars[i, 0], _rep = ReplaceChars[i, 1];worksheet.Cells.Replace(_find, _rep, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, false, false, false, false);}}_range = excel.get_Range(excel.Cells[1, 1], excel.Cells[1, 1]);_range.EntireRow.Insert(Type.Missing, Type.Missing);if (AddCols != null){int ref_col = 0;string ref_fname = "", ref_fvalue = "";Excel.Range _newrange;for (int ad = 0; ad < AddCols.GetLength(0); ad++){ref_col = (int)AddCols[ad, 0];ref_fname = AddCols[ad, 1].ToString();ref_fvalue = AddCols[ad, 2].ToString();_range = excel.get_Range(excel.Cells[1, ref_col], excel.Cells[1, ref_col]);_range.EntireColumn.Insert(Type.Missing, Type.Missing);//						ref_col=_newrange.Column;excel.Cells[1, ref_col] = ref_fname;if (maxrowid > 0){excel.Cells[2, ref_col] = ref_fvalue;_newrange = excel.get_Range(excel.Cells[2, ref_col], excel.Cells[2, ref_col]);_newrange.Copy(excel.get_Range(excel.Cells[2, ref_col], excel.Cells[maxrowid + 1, ref_col]));}}}worksheet.SaveAs(@_lastfile, Excel.XlFileFormat.xlAddIn, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);excel.ActiveWorkbook.Close(false, Type.Missing, Type.Missing);excel.Quit();rv[1] = "准备数据成功,共有记录" + maxrowid.ToString() + "行。字段" + (maxcolid - delcount + _addcol).ToString() + "列。";}catch (Exception e){rv[0] = "";rv[1] = e.Message;}return rv;
}

调用

调用示例代码如下:

string splitchar = "#";
int validResult = 4;
int origin = 65001;  //utf-8
bool ConsecutiveDelimiter=true; //如果为 true,则将连续分隔符视为一个分隔符,如“##” 则视为“#”
object[,] AddCols = new object[1, 3];
AddCols[0,0]=4;
AddCols[0,1]="导入标志";
AddCols[0,2] = "是";object[] rv2 = OpenTextToExcelFile("d:\\std.txt", "d:\\std.xls", splitchar, null, validResult, false, null, AddCols, 0, 1, 1, origin, ConsecutiveDelimiter);Response.Write("result:"+rv2[0] + "<br>" + rv2[1]);

导入的文本文件示例(以两个#号为分隔符)如下图:

 

 导入成功后如下图所示:

小结

1、OpenTextToExcelFile方法是一种兼容旧 EXCEL 版本的写法(如2003),我们可以根据实际需要进行改造。

2、许多参数是根据我们在使用过程中的实际需要而设置,以满足特殊需要,简化后期处理。

3、方法的核心是使用 EXCEL COM 的 OpenText 方法,关于该方法的详细介绍请参考如下链接:

https://learn.microsoft.com/zh-cn/office/vba/api/Excel.Workbooks.OpenText#parameters

4、原始文件的编码请参照本文Excel 的文本文件导入功能部分的图示所示,选择框中就是对应的编码代码,如65001表示UTF-8,这也是默认值。20936 则表示简体中文(GB2312-80)等等。

本方法仅做参考,感谢阅读,希望本文能够对您有所帮助。

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

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

相关文章

Apifox设置前置url的操作方法

目录 第一步 配置前置url&#xff0c;右上角设置-点击管理环境 第二步 填写请求方法和接口路径&#xff0c;切换成刚才设置的测试环境&#xff0c;点击发送 同一个域名遇到测试二个及以上接口&#xff0c;就可以通过设置前置url的方法来提升效率。操作也很简单&#xff0c;下…

【linux学习指南】linux 环境搭建

文章目录 &#x1f4dd;前言&#x1f320; 云服务器的选择&#x1f320;阿里云&#x1f320;腾讯云&#x1f320;华为云 &#x1f320;使用 XShell 远程登陆到 Linux&#x1f309;下载 XShell &#x1f320;查看 Linux 主机 ip&#x1f309; XShell 下的复制粘贴&#x1f309; …

供应链管理(SCM)把握好这5点,绝对差不到哪里去。

说到B端系统开发&#xff0c;框架是绕不开的话题&#xff0c;框架为开发者提供了诸多便利&#xff0c;同时也设置了条条框框&#xff0c;B系统工场为大家详细解读一下。 B端系统指的是面向企业或机构的后台管理系统&#xff0c;采用框架进行开发有以下优势和劣势&#xff1a; …

书生·浦语2.0(InternLM2)大模型实战--Day05 Lagent AgentLego 智能体应用搭建

视频地址&#xff1a;https://www.bilibili.com/video/BV1Xt4217728/ 课程文档&#xff1a;https://github.com/InternLM/Tutorial/tree/camp2/agent 课程作业&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/agent/homework.md 1. 概述 1.1 Lagent 是什么 La…

Spring Cloud Kubernetes 实践 服务注册发现、服务动态配置

一、Spring Cloud Kubernetes 随着云计算和微服务架构的不断发展&#xff0c;k8s 和Spring Cloud成为了当今技术领域的两大热门话题。k8s作为一个开源的容器编排平台&#xff0c;已经在自动化部署、扩展和管理方面取得了巨大的成功&#xff0c;而Spring Cloud则以其丰富的生态…

MySQL中索引的数据结构

2.3.1. 索引数据结构 索引就是能够提高查询速度的一种数据结构&#xff0c;在数据插入时就进行了排序&#xff08;会影响插入和更新的性能&#xff09;&#xff0c;索引广泛使用的是B树索引。 B树索引结构&#xff1a; 目前是基于磁盘排序效率最高的数据结构&#xff0c;树非…

Python 2 and3 兼容性问题的工具库之six使用详解

概要 在 Python 社区中&#xff0c;随着 Python 2 的逐渐退出舞台&#xff0c;许多项目需要同时兼容 Python 2 和 Python 3。为了简化这一任务&#xff0c;Python 社区开发了一个名为 six 的工具库&#xff0c;它提供了一组函数和工具&#xff0c;使得编写兼容 Python 2 和 Py…

Pandas Series的运算原来这么简单

Series的运算主要包括加法、减法、乘法和除法等基本算术运算。这些运算通常是按照索引对应计算的&#xff0c;如果两个Series的索引不同&#xff0c;则结果中对应位置将填充为NaN&#xff08;空值&#xff09;。 需要注意的是&#xff0c;在进行Series运算时&#xff0c;需要确…

文心一言 VS 讯飞星火 VS chatgpt (249)-- 算法导论18.2 2题

二、请解释在什么情况下&#xff08;如果有的话&#xff09;&#xff0c;在调用 B-TREE-INSERT 的过程中&#xff0c;会执行冗余的 DISK-READ 或 DISK-WRITE 操作。&#xff08;所谓冗余的 DISK-READ &#xff0c;是指对已经在主存中的某页做 DISK-READ 。冗余的 DISK-WRITE 是…

探索APP内测分发的全过程(APP开发)

什么是APP内测分发探索APP内测分发的全过程&#xff1f; APP内测分发是在应用程序开发过程中探索APP内测分发的全过程&#xff0c;开发者将应用程序的测试版或预发布版分发给特定用户进行测试、反馈和评估的一种方式。这是一个非常重要的环节&#xff0c;可以有效地提高应用的…

C语言——每日一题(反转链表)

一.前言 大家好&#xff01;今天又是每日一题环节。今天我为大家分享了一道单链表题——反转链表。 废话不多说&#xff0c;让我们直接进入正题吧。 二.正文 1.1题目信息 这是一道leetCode上面的一道题&#xff1a;https://leetcode.cn/problems/reverse-linked-list 1.2解…

227. 基本计算器 II

227. 基本计算器 II 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_227基本计算器II_单栈直接算_227基本计算器II_双栈 错误经验吸取 原题链接&#xff1a; 227. 基本计算器 II https://leetcode.cn/problems/basic-calculator-ii/ 完…

网络应用层之(6)L2TP协议详解

网络应用层之(6)L2TP协议 Author: Once Day Date: 2024年5月1日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…

[论文阅读] (32)南洋理工大学刘杨教授——网络空间安全和AIGC整合之道学习笔记及强推(InForSec)

首先祝大家五一节快乐&#xff01;《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给…

安卓四大组件之ContentProvider

目录 前言一、ContentProvider基础介绍1.1 简介1.2 作用1.3 实现原理 二、具体使用2.1 统一资源标识符&#xff08;URI&#xff09;2.2 MIME数据类型2.2.1 MIME类型组成2.2.2 常见的MIME类型2.2.3 ContentProvider根据 URI 返回MIME类型2.2.4 类型分类2.2.5 示例 2.3 ContentPr…

Java IO流(一)

1. IO流概述 1.1 什么是IO流 在计算机中&#xff0c;input/output&#xff08;I/O、i/o 或非正式的 io 或 IO&#xff09;是信息处理系统&#xff08;例如计算机&#xff09;与外界&#xff08;可能是人类或其他信息处理系统&#xff09;之间的通信。 输入是系统接收到的信号或…

基于ssm+vue+Mysql的药源购物网站

开发语言&#xff1a;Java框架&#xff1a;ssmJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.…

Ubuntu系统设置中文及中文输入法(手把手,学不会打我)

前言 最近开始搞C系统编程的学习&#xff0c;整了个Ubuntu系统&#xff0c;进去发现是英文系统&#xff0c;我一开始觉得也能接受&#xff0c;就当练英文&#xff0c;反正那些命令也都是用英文&#xff0c;不过后面等我暗转了一个Chrome并且开始用这里的软件去搜问题时&#x…

【08】JAVASE-面向对象-类和对象【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture&#xff1a;波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。…

Linux:冯诺依曼体系结构、操作系统、初识进程

文章目录 1.冯诺依曼体系结构总线与数据传输通路为什么有内存这个部分计算机存储结构 2.操作系统(Operator System)2.1 概念2.2 设计OS的目的2.3 理解“管理”先描述再组织 2.4 用户使用系统调用和库函数&#xff08;lib&#xff09;概念 总结 3.初识进程3.1 基本事实与引入3.2…