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. 第16篇 Shell脚本基础(一)

    1.什么是shell?shell是一个命令解释器. 是介于操作系统内核与用户之间的一个绝缘层.对于一个linux系统使用人员来说,shell是你驾驭类linux系统最基本的工具.所有的系统命令和工具再 ...

  2. linux 系统创建软连接

    ln -s /data/var/ /usr/local/smokeping/var 需求:/var/本身在/usr/local/smokeping/var下,想要把/usr/local/smokepi ...

  3. 图像处理笔记(1): bmp文件结构处理与显示

    1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面.那么Windows是如何显示图象的呢? ...

  4. FPGA应用及ARM-FPGA架构举例

    FPGA的应用非常广泛,通信领域,视频图像处理领域,汽车电子领域,消费电子领域,工业领域,数据处理领域等,都能看到FPGA的身影. 在设计中,FPGA通常和其他处理IC架构,完成整个设计.FPGA-A ...

  5. (转)pipe row的用法, Oracle split 函数写法.

    本文转载自:http://www.cnblogs.com/newsea/archive/2010/12/14/1905482.html 关于 pipe row的用法2009/12/30 14:53 = ...

  6. NoSuchBeanDefinitionException: No bean named 'shiroFilter' is defined

    以前运行正常的项目,过了一段时间再运行时出问题,打开链接无反应,无法访问Tomcat,空白页面. 经检查发现,在Tomcat log中有报错: NoSuchBeanDefinitionExceptio ...

  7. python开发mysql:Pymysql模块

    pymysql模块的使用 #1 基本使用 # import pymysql # conn=pymysql.connect(host='localhost',user='root',password=' ...

  8. python学习(八) 异常

    8.1 什么是异常 8.2 按自己的方式出错 如何引发异常,以及创建自己的异常类型. 8.2.1 raise语句 >>> raise Exception Traceback (mos ...

  9. PHP字符串的处理(二)-字符串的格式化

    1.字符串大小写的转换 strtoupper():将字符串全部转换为大写字母 strtolower():将字符串全部转换为小写字母 ucfirst():将字符串中的首字母转换为大写,其余字符不变 uc ...

  10. C# 泛型类型参数的约束

    在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...