Introduction

We produce professional business software, and we often have to import data from very simple Excel *.xslx-files: with some relevant rows and cells in the first worksheet of a workbook, and that's it. But we do not want to use large DLL's or third party software. Therefore we produced a small solution for our needs. It could be useful for you, too:

Using the code

Download the "Excel.dll" (8 kByte, .net 4.5!) and add it to your project. Or adapt the source code. Then work with the rows and cells (of the first worksheet) in the Excel file like so:

worksheet ws = worksheet.GetData(@"C:\ExcelFile.xlsx");
foreach (var row in ws.Rows)
foreach (var cell in row.Cells)
if (cell != null)
Console.WriteLine(cell.Text); // Do something with the cells

Here you open the Excel file, and iterate through the rows (and the cells of each row) within three lines of code.

Points of Interest

This article (written by M I developer) describes all the theoretical background, if you are interested in it. We only reduced our solution to the max using the integrated ZIP-library in .net 4.5 and the standard XML-serializer of .net.

If you want to adapt the solution to your needs: edit the simple source code for the Excel.dll. This is how it works:

Maybe you did not know that xlsx-files are ZIP-files. And the text strings of the Excel cells of all worksheets per workbook are always stored in a file named "xl/sharedStrings.xml", while the first worksheet is called "xl/worksheets/sheet1.xml".

So we have to unzip the Excel file and we have to deserialize the two mentioned XML files in it:

using System.IO.Compression;

public static worksheet GetData(string ExcelFileName)
{
worksheet ws; using (ZipArchive zipArchive = ZipFile.Open(ExcelFileName, ZipArchiveMode.Read))
{
worksheet.SharedStrings = worksheet.DeserializedZipEntry<sst>(zipArchive, @"xl/sharedStrings.xml");
ws = worksheet.DeserializedZipEntry<worksheet>(zipArchive, @"xl/worksheets/sheet1.xml");
}

For deserialization of an XML formatted ZIP-entry (see also this article written by Md. Rashim uddin) we use this generic method:

private static T DeserializedZipEntry<t>(ZipArchive ZipArchive, string ZipEntryName)
{
using (Stream stream
= ZipArchive.Entries.First<ziparchiveentry>(n => n.FullName.Equals(ZipEntryName)).Open())
return (T)new XmlSerializer(typeof(T), worksheet.RootAttr).Deserialize(XmlReader.Create(stream));
}

Therefore the XML-structures have to be reflected in our classes. Here you see the "sst"-class and the "SharedString"-class for the XML in the "shared strings table":

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="72" uniqueCount="6">
<si>
<t>Text A</t>
</si>
<si>
<t>Text B</t>
</si>
</sst>
public class sst
{
[XmlElement("si")]
public SharedString[] si; public sst()
{
}
} public class SharedString
{
public string t;
}

The same strategy we also use for the "worksheet" -XML-file in the ZIP-file. There we focus on the XML-elements and -attributes "row", "c", "v", "r" and "t". All the work is done again by the XmlSerializer:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<dimension ref="A1:F12"/>
<sheetViews>
<sheetView workbookViewId="0"></sheetView>
</sheetViews>
<sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
<sheetData>
<row r="1">
<c r="A1" t="s">
<v>0</v>
</c>
<c r="B1" t="s">
<v>1</v>
</c>
<c r="C1" t="s">
<v>2</v>
</c>
</row>
</sheetData>
</worksheet>
public class worksheet
{
[XmlArray("sheetData")]
[XmlArrayItem("row")]
public Row[] Rows; public class worksheet
{
}
}
public class Row
{
[XmlElement("c")]
public Cell[] FilledCells;
}
public class Cell
{
[XmlAttribute("r")]
public string CellReference;
[XmlAttribute("t")]
public string tType = "";
[XmlElement("v")]
public string Value;
}

Of course we have to do a little bit in order to convert the usual Excel cell references like "A1", "B1" and so on to column indices. That is done via a setter of "CellReference" in the "Cell"-class and a small method named "GetColumnIndex()":

[XmlAttribute("r")]
public string CellReference
{
get
{
return ColumnIndex.ToString();
}
set
{
ColumnIndex = worksheet.GetColumnIndex(value);
if (ColumnIndex > worksheet.MaxColumnIndex)
worksheet.MaxColumnIndex = ColumnIndex;
}
}

(Here we also derive the maximum column index for the whole worksheet.)

public static int GetColumnIndex(string CellReference)
{
string colLetter = new Regex("[A-Za-z]+").Match(CellReference).Value.ToUpper();
int colIndex = 0; for (int i = 0; i < colLetter.Length; i++)
{
colIndex *= 26;
colIndex += (colLetter[i] - 'A' + 1);
}
return colIndex - 1;
}

The last challenge has to do with the fact, that the Excel file does not contain empty Excel cells. So the tiny methods "ExpandRows()" and "ExpandCells()" handle that problem:

private void ExpandRows()
{
foreach (var row in Rows)
row.ExpandCells(NumberOfColumns);
} public void ExpandCells(int NumberOfColumns)
{
Cells = new Cell[NumberOfColumns];
foreach (var cell in FilledCells)
Cells[cell.ColumnIndex] = cell;
FilledCells = null;
}

In the end we have an array of all rows and an array of all cells for each row representing all columns of the specific Excel worksheet. Empty cells are null in the array, but the ColumnIndex of each cell in "Row.Cells[]" corresponds with the actual Excel column of each cell.

Besides, when you know that an Excel cell contains a date as its value, you can use this method for conversion:

public static DateTime DateFromExcelFormat(string ExcelDateValue)
{
return DateTime.FromOADate(Convert.ToDouble(ExcelDateValue));
}

Let me know how the total Excel.DLL works in your environment - and have fun with it!

C# How To Read .xlsx Excel File With 3 Lines Of Code的更多相关文章

  1. Read Excel file from C#

    Common way is: var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirec ...

  2. csharp:using OpenXml SDK 2.0 and ClosedXML read excel file

    https://openxmlexporttoexcel.codeplex.com/ http://referencesource.microsoft.com/ 引用: using System; u ...

  3. Read / Write Excel file in Java using Apache POI

    Read / Write Excel file in Java using Apache POI 2014-04-18 BY DINESH LEAVE A COMMENT About a year o ...

  4. Apache POI – Reading and Writing Excel file in Java

    来源于:https://www.mkyong.com/java/apache-poi-reading-and-writing-excel-file-in-java/ In this article, ...

  5. ExcelDataReader read excel file

    上篇文章向大家介绍了用DocumentFormat.OpenXml.dll读取excel的方法,这里再向大家介绍一种轻量级简便的方法,用的是Excel.dll,及ICSharpCode.SharpZi ...

  6. axios upload excel file

    axios upload excel file https://github.com/axios/axios/issues/1660 https://stackoverflow.com/questio ...

  7. NetSuite SuiteScript 2.0 export data to Excel file(xls)

    In NetSuite SuiteScript, We usually do/implement export data to CSV, that's straight forward: Collec ...

  8. Creating Excel File in Oracle Forms

    Below is the example to create an excel file in Oracle Forms.Pass the Sql query string to the below ...

  9. Formatting Excel File Using Ole2 In Oracle Forms

    Below is the some useful commands of Ole2 to format excel file in Oracle Forms.-- Change font size a ...

随机推荐

  1. Java 程序员容易犯的10个SQL错误

    Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,能否完美的将两者结合起来完全得依靠编程人员的水准: 技能(任何人都能容易学会命令式编程) 模式(有些人用“模式-模式”,举个例子,模式可 ...

  2. super,this

    要说super就先要说this."this",作为一个特殊的关键字,它的规则如下: 1.可以表示构造函数传递.this(a,b)表示调用另外一个构造函数.这里面的this就是一个特 ...

  3. mongo数据排序和分页显示

    数据排序 使用sort()1 升序-1 降序自然排序 数据插入的顺序$natural db.stu.drop(); db.stu.insert({,,"address":" ...

  4. 张瀚荣:如何用UE4制作3D动作游戏

    转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...

  5. Ehcache入门介绍一

    EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. 特性有: 1. 快速轻量 Ehcache的线程机制是为大型高并发系统设 ...

  6. C++学习路线(转载)

    随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者.而在今天,它又扮演着什么样重要的角色呢?请往下看: 后端服务器,移 ...

  7. 最长上升子序列(LIS)

    最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS.排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个序列d[1..9] = ...

  8. 【281】◀▶ arcpy.mapping 常用类说明

    arcpy.mapping 教程入门 arcpy.mapping 指导原则 按字母顺序排序的 arcpy.mpping 类列表 按字母顺序排序的 arcpy.mpping 函数列表 按字母顺序排序的 ...

  9. Centos 6.5 python 2.6.6 升级到 2.7

    1.查看python的版本 [root@localhost ~]# python -V Python 2.6.6 2.安装python 2.7.3 [root@localhost ~]# yum in ...

  10. linux 目录和用户权限命令

    1.linux 修改文件目录所有者 例:要将当前目录下名 title 的文件夹及其子文件的所有者改为geust组的su用户,方法如下: #chown -R su.geust title -R 递归式地 ...