一个用微软官方的OpenXml读写Excel 目前网上不太普及的方法。
新版本的xlsx是使用新的存储格式,貌似是处理过的XML。
传统的excel处理方法,我真的感觉像屎。用Oldeb不方便,用com组件要实际调用excel打开关闭,很容易出现死。
对于OpenXML我网上搜了一下,很多人没有介绍。所以我就这里推荐下,相信会成为信息系统开发的必备。
先写出个例子,会发现如此的简介:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using XFormular.config;
- using System.IO;
- using com.xtar.amfx;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Data;
- namespace XFormular.test
- {
- class Class1
- {
- public void test()
- {
- DataTable table = new DataTable("");
- table.Columns.Add("");
- for (int i = ; i < ; i++)
- {
- DataRow row = table.NewRow();
- row[] = i;
- table.Rows.Add(row);
- }
- List<DataTable> lsit = new List<DataTable>();
- lsit.Add(table);
- OpenXmlSDKExporter.Export(AppDomain.CurrentDomain.BaseDirectory + "\\excel.xlsx", lsit);
- }
- }
- }
写出代码:
- using System;
- using System.IO;
- using System.Windows.Forms;
- using DocumentFormat.OpenXml;
- using DocumentFormat.OpenXml.Packaging;
- using DocumentFormat.OpenXml.Spreadsheet;
- using DocumentFormat.OpenXml.Extensions;
- using System.Collections.Generic;
- using System.Data;
- using System.Text.RegularExpressions;
- namespace XFormular
- {
- //http://simpleooxml.codeplex.com/
- //http://www.pin5i.com/showtopic-21817.html
- //http://blog.csdn.net/lbj147123/article/details/6603942
- class OpenXmlSDKExporter
- {
- private static string[] Level = {"A", "B", "C", "D", "E", "F", "G",
- "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
- "U", "V", "W", "X", "Y", "Z" };
- public static List<DataTable> Import(string path)
- {
- List<DataTable> tables = new List<DataTable>();
- if (path.EndsWith(ExcelHelper.POSTFIX_SVN))
- return tables;
- using (MemoryStream stream = SpreadsheetReader.StreamFromFile(path))
- {
- using (SpreadsheetDocument doc = SpreadsheetDocument.Open(stream, true))
- {
- foreach (Sheet sheet in doc.WorkbookPart.Workbook.Descendants<Sheet>())
- {
- DataTable table = new DataTable(sheet.Name.Value);
- WorksheetPart worksheet = (WorksheetPart)doc.WorkbookPart.GetPartById(sheet.Id);
- List<string> columnsNames = new List<string>();
- foreach (Row row in worksheet.Worksheet.Descendants<Row>())
- {
- foreach (Cell cell in row)
- {
- string columnName = Regex.Match(cell.CellReference.Value, "[a-zA-Z]+").Value;
- if (!columnsNames.Contains(columnName))
- {
- columnsNames.Add(columnName);
- }
- }
- }
- columnsNames.Sort(CompareColumn);
- foreach (string columnName in columnsNames)
- {
- table.Columns.Add(columnName);
- }
- foreach (Row row in worksheet.Worksheet.Descendants<Row>())
- {
- DataRow tableRow = table.NewRow();
- table.Rows.Add(tableRow);
- foreach (Cell cell in row)
- {
- string columnName = Regex.Match(cell.CellReference.Value, "[a-zA-Z]+").Value;
- tableRow[columnName] = GetValue(cell, doc.WorkbookPart.SharedStringTablePart);
- }
- }
- if (table.Rows.Count <= )
- continue;
- if (table.Columns.Count <= )
- continue;
- tables.Add(table);
- }
- }
- }
- return tables;
- }
- public static String GetValue(Cell cell, SharedStringTablePart stringTablePart)
- {
- if (cell.ChildElements.Count == )
- return null;
- //get cell value
- String value = cell.CellValue.InnerText;
- //Look up real value from shared string table
- if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
- value = stringTablePart.SharedStringTable
- .ChildElements[Int32.Parse(value)]
- .InnerText;
- return value;
- }
- public static void Export(string path, List<DataTable> tables)
- {
- using (MemoryStream stream = SpreadsheetReader.Create())
- {
- using (SpreadsheetDocument doc = SpreadsheetDocument.Open(stream, true))
- {
- SpreadsheetWriter.RemoveWorksheet(doc, "Sheet1");
- SpreadsheetWriter.RemoveWorksheet(doc, "Sheet2");
- SpreadsheetWriter.RemoveWorksheet(doc, "Sheet3");
- foreach (DataTable table in tables)
- {
- WorksheetPart sheet = SpreadsheetWriter.InsertWorksheet(doc, table.TableName);
- WorksheetWriter writer = new WorksheetWriter(doc, sheet);
- SpreadsheetStyle style = SpreadsheetStyle.GetDefault(doc);
- foreach (DataRow row in table.Rows)
- {
- for (int i = ; i < table.Columns.Count; i++)
- {
- string columnName = SpreadsheetReader.GetColumnName("A", i);
- string location = columnName + (table.Rows.IndexOf(row) + );
- writer.PasteText(location, row[i].ToString(), style);
- }
- }
- writer.Save();
- }
- SpreadsheetWriter.StreamToFile(path, stream);//保存到文件中
- }
- }
- }
- private static int CompareColumn(string x, string y)
- {
- int xIndex = Letter_to_num(x);
- int yIndex = Letter_to_num(y);
- return xIndex.CompareTo(yIndex);
- }
- /// <summary>
- /// 数字26进制,转换成字母,用递归算法
- /// </summary>
- /// <param name="value"></param>
- /// <returns></returns>
- private static string Num_to_letter(int value)
- {
- //此处判断输入的是否是正确的数字,略(正在表达式判断)
- int remainder = value % ;
- //remainder = (remainder == 0) ? 26 : remainder;
- int front = (value - remainder) / ;
- if (front < )
- {
- return Level[front - ] + Level[remainder];
- }
- else
- {
- return Num_to_letter(front) + Level[remainder];
- }
- //return "";
- }
- /// <summary>
- /// 26进制字母转换成数字
- /// </summary>
- /// <param name="letter"></param>
- /// <returns></returns>
- private static int Letter_to_num(string str)
- {
- //此处判断是否是由A-Z字母组成的字符串,略(正在表达式片段)
- char[] letter = str.ToCharArray(); //拆分字符串
- int reNum = ;
- int power = ; //用于次方算值
- int times = ; //最高位需要加1
- int num = letter.Length;//得到字符串个数
- //得到最后一个字母的尾数值
- reNum += Char_num(letter[num - ]);
- //得到除最后一个字母的所以值,多于两位才执行这个函数
- if (num >= )
- {
- for (int i = num - ; i > ; i--)
- {
- power = ;//致1,用于下一次循环使用次方计算
- for (int j = ; j < i; j++) //幂,j次方,应该有函数
- {
- power *= ;
- }
- reNum += (power * (Char_num(letter[num - i - ]) + times)); //最高位需要加1,中间位数不需要加一
- times = ;
- }
- }
- //Console.WriteLine(letter.Length);
- return reNum;
- }
- /// <summary>
- /// 输入字符得到相应的数字,这是最笨的方法,还可用ASIICK编码;
- /// </summary>
- /// <param name="ch"></param>
- /// <returns></returns>
- private static int Char_num(char ch)
- {
- switch (ch)
- {
- case 'A':
- return ;
- case 'B':
- return ;
- case 'C':
- return ;
- case 'D':
- return ;
- case 'E':
- return ;
- case 'F':
- return ;
- case 'G':
- return ;
- case 'H':
- return ;
- case 'I':
- return ;
- case 'J':
- return ;
- case 'K':
- return ;
- case 'L':
- return ;
- case 'M':
- return ;
- case 'N':
- return ;
- case 'O':
- return ;
- case 'P':
- return ;
- case 'Q':
- return ;
- case 'R':
- return ;
- case 'S':
- return ;
- case 'T':
- return ;
- case 'U':
- return ;
- case 'V':
- return ;
- case 'W':
- return ;
- case 'X':
- return ;
- case 'Y':
- return ;
- case 'Z':
- return ;
- }
- return -;
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Data;
- using System.Data.OleDb;
- namespace xtar_biz_codegen
- {
- class ExcelHelper
- {
- public static string POSTFIX_97 = "XLS";
- public static string POSTFIX_03 = "XLSX";
- }
- }
最后附送一个项目文件,可以自己测试:
http://pan.baidu.com/s/1msFuY
一个用微软官方的OpenXml读写Excel 目前网上不太普及的方法。的更多相关文章
- #应用openxml读写excel代码
这个例子比较简单,没有考虑格式之类的问题. using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadshe ...
- Python: 读写Excel(openpyxl / win32com.client)
项目周报汇报的时候要做数据汇总,总是要从不同的excel文件中去获取数据最后汇总到一个excel表里面,所以决定用python直接写个自动化脚本来自动执行. 用python来读写excel,目前找了2 ...
- 微软官方的Excel android 移动版的折腾
微软官方的Excel android 移动版,有重大bug.害我折腾了一天多时间.最终确认是Excel自身的问题. 现象描述:手机上新建或是保存excel后.放到电脑上,不能打开.提示”Excel在B ...
- 微软官方 Win 11 “体检工具”太烂了?开发者自己做了一个
1.Win 10 免费升级到 Win 11 最近微软官方终于宣布了 Windows 11,不仅带来了全新的 UI,而且还有很多新功能:比如支持 Android 应用. 虽然微软官方已说明 Win 10 ...
- 【原创】.NET读写Excel工具Spire.Xls使用(1)入门介绍
在.NET平台,操作Excel文件是一个非常常用的需求,目前比较常规的方法有以下几种: 1.Office Com组件的方式:这个方式非常累人,微软的东西总是这么的复杂,使用起来可能非常不便,需要安装E ...
- 【原创】.NET读写Excel工具Spire.Xls使用(3)单元格控制
本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html .NET读写Excel工具Spire.Xls使用文章 ...
- .NET读写Excel工具Spire.Xls使用(1)入门介绍
原文:[原创].NET读写Excel工具Spire.Xls使用(1)入门介绍 在.NET平台,操作Excel文件是一个非常常用的需求,目前比较常规的方法有以下几种: 1.Office Com组件的方式 ...
- 使用NPOI读写Excel、Word
NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 ...
- 【原创】.NET读写Excel工具Spire.Xls使用(4)对数据操作与控制
本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html .NET读写Excel工具Spire.Xls使用文章 ...
随机推荐
- 【转载】最完美解决Nginx部署ThinkPHP项目的办法
网上通用解决方法的配置如下: server { ... location / { index index.htm index.html index.php; #访问路径的文件不存在则重写URL转交给T ...
- rsync排除文件同步
排除扩展名为log的文件 rsync -ave ssh --exclude '*.log' root@192.168.168.188:/website/abc.com/* /website/abc.c ...
- PowerPoint
工具/原料 PowerPoint 2007 百度经验:jingyan.baidu.com 一.PowerPoint2007基础知识 1 桌面快捷方式:也可以“开始”菜单→程序→Microsoft Of ...
- Spring笔记--0907
包含ioc和aop两大核心概念 aop----事务管理 spring框架运用的设计模式(查一下) ---------------------------------------Ioc(控制反转)和Di ...
- 虚拟机安装Ubuntu到U盘
这篇经验中特指系统安装到U盘,系统在U盘上,不是双系统,不会改变源系统的设置.只需在启动的时候选择启动路径,就可以从U盘启动你的系统.本文仅仅Ubuntu系统,举一反三可以按照此方法安装各种各样的系统 ...
- python 元类
转载自 http://blog.jobbole.com/21351/ 类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大 ...
- java的 new 关键字
java的new关键字想必大家都知道这是实例化一个对象.没错,也是为新对象分配内存空间. 比如new MyDate(22,7,1964)这样一个案例,他的完成需要四部: 一.为新对象分配内存空间,将M ...
- WP7系统托盘和应用程序栏
(一)系统托盘和应用程序栏系统托盘(1)显示系统级别的状态信息(2)Apps能隐藏和显示系统托盘Micosoft.Phone.Shell.SystemTray.IsVisible=true;应用程序栏 ...
- [CSDN转载]致C语言初学者—指针注意项
在论坛里经常见到一些新人对指针提出一些问题,作为一个经历过许多错误后的新手,我想把自己的经历说出来,避免让后来人继续这样的错误. 在讲解指针之前,需要理解一下内存空间.内存是随机存取器,计算机上 ...
- 打印文本中的所有单词,并且打印每个单词出现的行号,非实义单词不考虑(TCPL,练习6-3)
建立一棵二叉树,每个接单存放单词以及指向一个链表的指针,以及指向左右节点的指针.链表内存放行号以及指向下一个链表节点的指针. 每录入一个单词,先寻找二叉树,再寻找它的链表,分别将单词和行号插入二叉树和 ...