share
Stack OverflowHow do I create an Excel (.XLS and .XLSX) file in C# without installing Microsoft Office?
[+2167] [48] mistrmark
[2008-09-29 22:30:28]
[ c# .net excel file-io ]
[ https://stackoverflow.com/questions/151005/how-do-i-create-an-excel-xls-and-xlsx-file-in-c-without-installing-microsof ]

How can I create an Excel spreadsheet with C# without requiring Excel to be installed on the machine that's running the code?

(69) @Mike The "without requiring Excel to be installed" piece has nothing to do with being professional. It's about dependencies. The original text of the question was worded as: "Ideally, I would like open source so I don't have to add any third party dependencies to my code, and I would like to avoid using Excel directly to create the file (using OLE Automation.)" It's unfortunate the question was drastically simplified. - Tony
(10) Assuming you were trying to do something sans library or external code, I can't speak for xls file, but for xlsx files, why not start by taking an existing one, renaming it to a zip file and exploring the contents? A little bit of reverse engineering will tell you quite a bit. There are several different xml files and rels files in the various folders and subfolders. Try exploring that and see if it's something you can replicate or see if you can find documentation on the various xml namespaces/schemas. - Alexander Ryan Baggett
[+1190] [2010-04-08 21:36:03] Mike Webb [ACCEPTED]

You can use a library called ExcelLibrary. It's a free, open source library posted on Google Code:

ExcelLibrary [1]

This looks to be a port of the PHP ExcelWriter that you mentioned above. It will not write to the new .xlsx format yet, but they are working on adding that functionality in.

It's very simple, small and easy to use. Plus it has a DataSetHelper that lets you use DataSets and DataTables to easily work with Excel data.

ExcelLibrary seems to still only work for the older Excel format (.xls files), but may be adding support in the future for newer 2007/2010 formats.

You can also use EPPlus [2], which works only for Excel 2007/2010 format files (.xlsx files). There's also NPOI [3] which works with both.

There are a few known bugs with each library as noted in the comments. In all, EPPlus seems to be the best choice as time goes on. It seems to be more actively updated and documented as well.

Also, as noted by @АртёмЦарионов below, EPPlus has support for Pivot Tables and ExcelLibrary may have some support ( Pivot table issue in ExcelLibrary [4])

Here are a couple links for quick reference:
ExcelLibrary [5] - GNU Lesser GPL [6]
EPPlus [7] - GNU (LGPL) - No longer maintained [8]
EPPlus 5 [9] - Polyform Noncommercial - Starting May 2020 [10]
NPOI [11] - Apache License [12]

Here some example code for ExcelLibrary:

Here is an example taking data from a database and creating a workbook from it. Note that the ExcelLibrary code is the single line at the bottom:

//Create the data set and table
DataSet ds = new DataSet("New_DataSet");
DataTable dt = new DataTable("New_DataTable");

//Set the locale for each
ds.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;

//Open a DB connection (in this example with OleDB)
OleDbConnection con = new OleDbConnection(dbConnectionString);
con.Open();

//Create a query and fill the data table with the data from the DB
string sql = "SELECT Whatever FROM MyDBTable;";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter adptr = new OleDbDataAdapter();

adptr.SelectCommand = cmd;
adptr.Fill(dt);
con.Close();

//Add the table to the data set
ds.Tables.Add(dt);

//Here's the easy part. Create the Excel worksheet from the data set
ExcelLibrary.DataSetHelper.CreateWorkbook("MyExcelFile.xls", ds);

Creating the Excel file is as easy as that. You can also manually create Excel files, but the above functionality is what really impressed me.

[1] https://code.google.com/archive/p/excellibrary/
[2] https://github.com/JanKallman/EPPlus
[3] https://github.com/tonyqus/npoi
[4] https://code.google.com/archive/p/excellibrary/issues/98
[5] https://code.google.com/archive/p/excellibrary/
[6] https://www.gnu.org/licenses/lgpl.html
[7] https://github.com/JanKallman/EPPlus
[8] https://github.com/JanKallman/EPPlus#license
[9] https://www.epplussoftware.com/
[10] https://www.epplussoftware.com/en/LicenseOverview
[11] https://github.com/tonyqus/npoi
[12] https://github.com/tonyqus/npoi/blob/master/LICENSE

(268) ExcelLibrary has been superseded by the exceptional EPPlus - epplus.codeplex.com. Jan updates it regularly. Have been using it and it is one of the finest open source projects we've worked with. - Mark A
(4) It should be noted that ExcelLibrary has a lot of performance issues when dealing with large datasets(larger than 5000 rows with lots of columns). Currently doing a heavy modification of the code base at work so we can use it in a project. - rossisdead
EPPlus seems far less buggy than ExcelLibrary, BUT it is GPL and therefore only a solution for open source projects. - Seth
EPPlus is actually still technically GPL because it is a derived work (i.e. the code base is still based off of ExcelLibrary, and since that is GPL so is EPPlus ... you can't make some changes to GPL code and slap a LGPL license on it). Does anyone know of a way to write to Excel using either commercial code or true LGPL (or similarly licensed code). - Beep beep
ExcelLibrary doesn't work anymore. If you want to write Excel 2003 files (.xls) this library is working great: CSharpJExcel sourceforge.net/projects/jexcelapi Make sure to download the C# port. - Chris
(11) What about ClosedXML? I may prove to be useful in your projects. - Amadeus Sanchez
(1) I tried ExcelLibrary, all it could do was produce a 'corrupted file', nothing fancy just 3 columns, small file. Excel 2016 wouldn't open. Tried the automatic file generation rom DataTable. - Vega4
(2) EPPlus is LGPL up to version 5. If you use version 5 or above in your code, an exception will be thrown if you do not have a license key. - Britt Kelly
1
[+647] [2010-03-29 12:25:54] Jan Källman

If you are happy with the xlsx format, try my library, EPPlus. It started with the source from ExcelPackage, but since became a total rewrite.

It supports ranges, cell styling, charts, shapes, pictures, named ranges, AutoFilter, and a lot of other stuff.

You have two options:

  • EPPlus 4 [1], licensed under LGPL (original branch, developed until 2020)

  • EPPlus 5 [2], licensed under Polyform Noncommercial 1.0.0 (since 2020).

From the EPPlus 5 readme.md:

With the new license EPPlus is still free to use in some cases, but will require a commercial license to be used in a commercial business.

EPPlus website: https://www.epplussoftware.com/

[1] https://github.com/JanKallman/EPPlus
[2] https://github.com/EPPlusSoftware/EPPlus

(18) The examples were helpful. I was able to change my code from using Microsoft interop library (horribly slow) to this library (version 4.x) in a couple hours. My benchmark writes a file with two tabs and about 750,000 cells. Using MS interop it took 13 minutes. Using EPPlus it took 10 seconds, a roughly 80x speedup. Very happy! - Paul Chernoch
@JanKällman You should update your CodePlex page to show you've got these methods available: LoadFromCollection<T>, LoadFromDataTable etc. (found via here) - PeterX
(3) For clarity in this thread, the LGPL allows the software to be linked to without the infective part of the GPL occuring. You only need to open source changes you make to ClosedXml or if you directly put the source code (as opposed to referencing the ClosedXml assemblies) inside of your application then you need to open source your application. - Chris Marisic
(9) @Paul Chernoch: We populate large Excel sheets with interop very quickly. The secret is to do a bulk update. Create a object [,] block, populate that, then write that matrix to Excel at one time: excelWorksheet.get_Range(range).Value2 = block; - Marc Meketon
(3) I don't think suggesting a paid product is a solution to this question. - Niels Abildgaard
2
[+222] [2011-08-16 09:25:58] Pellared

And what about using Open XML SDK 2.0 for Microsoft Office?

A few benefits:

  • Doesn't require Office installed
  • Made by Microsoft = decent MSDN documentation
  • Just one .Net dll to use in project
  • SDK comes with many tools like diff, validator, etc

Links:

[1] https://github.com/officedev/open-xml-sdk
[2] https://learn.microsoft.com/en-us/office/open-xml/open-xml-sdk
[3] https://learn.microsoft.com/en-us/office/open-xml/how-do-i
[4] https://blogs.msdn.microsoft.com/brian_jones/2010/03/12/announcing-the-release-of-the-open-xml-sdk-2-0/
[5] https://blogs.msdn.microsoft.com/brian_jones/2010/06/22/writing-large-excel-files-with-the-open-xml-sdk/

(5) Important to note that the DLL for this is just over 5 MB and limited to Office 2007 formats. But certainly the easiest and fastest solution which works for me. - Josh Brown
(20) Just a heads up that v2.5 is out and can be downloaded here. - Snuffleupagus
(15) The SDK models the XML into classes, so that each XML tag is mapped to a tag, and then you have to build the class hierarchy (each instance has a collection of child instances/tags) correctly. This means you have to know the XML structure of an Excel file, which is very complicated. It's much easier to use a wrapper such as EPPlus, mentioned above, which simplifies things. - Tsahi Asher
(2) A great sample of Microsoft Open XML SDK - Open XML Writer can be found at polymathprogrammer.com/2012/08/06/… Or see Stack Overflow solution stackoverflow.com/questions/11370672/… - Greg
(5) I found Microsoft Open XML SDK's Open XML Writer to be great. Using the solutions above, (Especially Vincent Tom's sample (Poly Math)), it's easy to build a writer that streams through big sets of data, and writes records in a manner similiar and not too much more complex to what you'd do for CSV; but that you're instead writing xml. Open XML is the mindset that Microsoft considers it's new Office formats in. And you can always rename them from .xslx to .zip files if you feel like poking at their XML contents. - Greg
(2) Please note that Open XML SDK are now open source and hosted on github. Also you don't need to install the SDK, just fire-up nuget and DocumentFormat.OpenXml is all you need. It works with .net standard 1.3. - horeaper
How interesting it was and your answer made me learn this. I have just entered the field of programming and such content is interesting to me. - elnaz jangi
(1) Don't forget to download the OpenXML Productivity Tool from the Microsoft site when you use this API. The way I work: Create a document with the content and format that I want in Excel and save it. Open it with the Tool. Scrape the code that I'm interested in from the reflected code in the tool, start from there. I also use the tool to verify and error check my output. When I want to put a new feature into my code, I use the tools "Diff" feature to figure out how the feature should be coded. It's really an essential OpenXML dev tool - Flydog57
3
[+179] [2009-06-20 20:48:26] Leniel Maccaferri

I've used with success the following open source projects:

  • ExcelPackage for OOXML formats (Office 2007)

  • NPOI for .XLS format (Office 2003). NPOI 2.0 [1] (Beta) also supports XLSX.

Take a look at my blog posts:

Creating Excel spreadsheets .XLS and .XLSX in C# [2]

NPOI with Excel Table and dynamic Chart [3]

[1] https://github.com/tonyqus/npoi
[2] https://www.leniel.net/2009/07/creating-excel-spreadsheets-xls-xlsx-c.html
[3] https://www.leniel.net/2009/10/npoi-with-excel-table-and-dynamic-chart.html

(7) A note on NPOI - Row and Column references are zero-based. Does work well for populating an existing template. - John M
4
[+120] [2008-09-29 22:41:09] Panos

You can use OLEDB to create and manipulate Excel files. Check this: Reading and Writing Excel using OLEDB [1].

Typical example:

using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\temp\\test.xls;Extended Properties='Excel 8.0;HDR=Yes'"))
{
  conn.Open();
  OleDbCommand cmd = new OleDbCommand("CREATE TABLE [Sheet1] ([Column1] string, [Column2] string)", conn);
  cmd.ExecuteNonQuery();
}

EDIT - Some more links:

[1] https://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel-using-OLEDB
[2] https://devblogs.microsoft.com/scripting/hey-scripting-guy-how-can-i-read-from-excel-without-using-excel/
[3] http://support.microsoft.com/kb/316934
[4] http://davidhayden.com/blog/dave/archive/2006/05/26/2973.aspx

(5) Can someone confirm if this works when running in x64? I am pretty sure Jet only works if your app is compiled or running in 32-bit mode. - Lamar
(3) I've just tested this connection and it failed on a Windows Server 2008 R2 x64 RC, seems like one have to install the 2007 Office System Driver: Data Connectivity Components [microsoft.com/downloads/… - Chris Richner
(28) Be very careful with this -- it's a big ugly cludge (for example, sometimes it guesses a column type and discards all the data that does not fit). - dbkk
(9) One should be very careful if using this method. I've found it very flaky for data that isn't in a perfect format. - Kenny Mann
(11) As a person who had to use OleDb in a big project, I say STAY AWAY FROM IT! It sometimes is not able to retrieve a cell value just because it couldn't understand the format. It doesn't have a delete operation. It works totally different and unpredictable even with a slightest provider change. I'd say go for a proven commercial solution. - platypus
(1) Microsoft has upgraded Jet, try this link stackoverflow.com/questions/14401729/… - Justin
(2) At a previous job, we used Microsoft Access Database Engine 2010 Redistributable. It took the form of an OLEDB driver that allowed reading from and writing to Excel files, as well as Access format files. Note that this download does not require you to install the entire Office suite. Note also that it comes in both 32-bit and 64-bit flavors. It is very important that you match the 32-bit or 64-bit version to the architecture of the host process that will access the file(s). In our case, the host process was SSIS. - Stephen G Tuggy
Two of the links are dead. - MT1
@platypus Like LINQ it's supposed to be used for queries not updates. - Alan B
5
[+84] [2009-01-24 18:33:17] Joe Erickson

The commercial solution, SpreadsheetGear for .NET [1] will do it.

You can see live ASP.NET (C# and VB) samples here [2] and download an evaluation version here [3].

Disclaimer: I own SpreadsheetGear LLC

[1] https://www.spreadsheetgear.com/
[2] https://www.spreadsheetgear.com/support/samples/
[3] https://www.spreadsheetgear.com/downloads/register.aspx

(15) You have a great product but I think a lot of people here are expecting free solutions. That might explain the down votes. - md1337
I don't think recommending a paid solution really explains how to solve this problem. - Niels Abildgaard
6
[+72] [2008-09-29 22:37:59] Forgotten Semicolon

An extremely lightweight option may be to use HTML tables. Just create head, body, and table tags in a file, and save it as a file with an .xls extension. There are Microsoft specific attributes that you can use to style the output, including formulas.

I realize that you may not be coding this in a web application, but here is an example [1] of the composition of an Excel file via an HTML table. This technique could be used if you were coding a console app, desktop app, or service.

[1] https://web.archive.org/web/20051122071945/http://jasonhaley.com/blog/archive/2004/03/20/9583.aspx

(9) It's so ad hoc but it works (not to mention excel issuing a warning on opening) and is so simple, it deserves to have a place as a solution. Though only for showing that you can export an excel file :)) - Luka Ramishvili
(3) This solution worked fine for me, just note you cannot use .xlsx extension - Jill
Some people at my organization can't open excel files made this way in Office 2010 and above. Don't know what the problem is, but I had to roll my own OpenXML implementation. (see Sogger's answer) - Kristen Hammack
(1) An even more lightweight version is to just create a csv file, which Windows associates with Excel. - John Coleman
Watch out for security warnings appearing to your user if you do this: "Warning, the content of the file doesn't match the extension". Particularly alarming when you're doing a download from your bank. I wouldn't rcommend pursuing the approach mentioned in this answer - Caius Jard
7
[+69] [2009-06-01 15:45:06] Nate

A few options I have used:

If XLSX is a must: ExcelPackage [1] is a good start but died off when the developer quit working on it. ExML picked up from there and added a few features. ExML [2] isn't a bad option, I'm still using it in a couple of production websites.

For all of my new projects, though, I'm using NPOI [3], the .NET port of Apache POI [4]. NPOI 2.0 (Alpha) [5] also supports XLSX.

[1] https://archive.codeplex.com/?p=ExcelPackage
[2] https://archive.codeplex.com/?p=exml
[3] https://github.com/tonyqus/npoi
[4] https://poi.apache.org/
[5] https://github.com/tonyqus/npoi

Be careful with ExcelPackage if you need to support XLS. I had a hard time with it and eventually switched to ExcelLibrary. - Jeremy
Definitely true. ExcelPackage/ExML is only a good option if you need the XLSX support. - Nate
(5) Note that ExcelPackage has a successor: EPPlus (epplus.codeplex.com) which supports XLSX. My only concern, compared to NPOI for example, is performance, e.g. when there is a lot of columns. - Pragmateek
8
[+63] [2010-11-23 16:33:00] Manuel

If you're creating Excel 2007/2010 files give this open source project a try: https://github.com/closedxml/closedxml

It provides an object oriented way to manipulate the files (similar to VBA) without dealing with the hassles of XML Documents. It can be used by any .NET language like C# and Visual Basic (VB).

ClosedXML allows you to create Excel 2007/2010 files without the Excel application. The typical example is creating Excel reports on a web server:

var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = "Hello World!";
workbook.SaveAs("HelloWorld.xlsx");

(9) I tried using this in a project that builds pretty large Excel sheets. Excellent library, but extremely poor in performance. I just did a comparison for the project I'm working on: ClosedXML (v 0.53.3) took 92,489 ms whereas EPPlus (v 2.9.03, for testing - we can't use because it's GPL) took 16,500 ms. - Druid
(1) @Druid the license is LGPL assuming you don't modify the source code to ClosedXML it is free to use epplus.codeplex.com/license - Chris Marisic
I appreciate that ClosedXML is open source (MIT). At the time I wrote this the LGPL licensed EPPlus project on GitHub is archived and its last release was in January 2019. - Jeremy Cook
9
[+55] [2008-09-29 22:34:23] GEOCHET

You actually might want to check out the interop classes available in C# (e.g. Microsoft.Office.Interop.Excel. You say no OLE (which this isn't), but the interop classes are very easy to use. Check out the C# Documentation here [1] (Interop for Excel starts on page 1072 of the C# PDF).

You might be impressed if you haven't tried them.

Please be warned of Microsoft's stance [2] on this:

Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.

[1] http://msdn.microsoft.com/en-us/library/ms173186(VS.80).aspx
[2] https://support.microsoft.com/en-in/help/257757/considerations-for-server-side-automation-of-office

(6) But you have to make sure that you dispose of everything manually, otherwise you will leak memory - MagicKat
(11) @Ricky B: Also, in my experience with the interop is that it does use excel. Every time we used it, if Excel wasn't installed on the machine, we would get COM exceptions. - MagicKat
(1) With the OLE, even with very careful disposals, it eventually leaks memory or crashes. This is argueably OK for attended applications/ workstations, but for servers is not recommended (MS has a KB stating this). For our server, we just reboot it nightly. Again, that works OK. - Jennifer Zouak
(12) @Geoffrey: ah OK you are going to make me work for it :) --> support.microsoft.com/kb/257757 Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application... - Jennifer Zouak
(4) I'm coming to this discussion after struggling more than a week on interop, and unless your needs are very simple, this is not gonna work. The support for formatting your spreadsheet is abysmal, which is arguably the reason for generating an .xls file and not just a flat .csv file. For example, have you tried outputting more than 911 characters in a cell, or have you tried setting the width of merged cells in a consistent manner? I have, and I can't tell you how much I hate this crap now... Do yourself a favor and go with one of the free libraries mentioned on this discussion. - md1337
I haven't changed Interop for EPPlus yet (but already on the half way) so I don't really know how much better life is with it, but dealing with Interop I got so much pain in very surprising cases nearly every time I needed something more complex than just create .xls/.xlsx file with simple table inside. And mentioned above 'twice-check-to-dispose-everything-magic' is one of that everyday pain. But yeah, it works, and most of the time it's enough. - pkuderov
(1) Warning the Microsoft.Office.Interops library has a dependency on Excel being installed. Thus does not answer the user's question - Mark
(2) He literally says he does not want to have to install office - JSON
If you are using Powershell or dotnet, ImportExcel is great 1] You do not need excel or office installed, and 2] no COM is required -- I use pwsh on Amazon linux lambdas to dynamically attach excel sheets for emails - ninMonkey
10
[+53] [2009-02-12 15:04:46] Petr Snobelt

You can use ExcelXmlWriter [1].

It works fine.

[1] https://www.carlosag.net/Tools/ExcelXmlWriter/

This library works well and is easy to use -- but only supports the .xls (Excel 2003) format. - Niels Abildgaard
11
[+38] [2011-12-05 12:08:36] Mike Gledhill

Here's a completely free C# library, which lets you export from a DataSet, DataTable or List<> into a genuine Excel 2007 .xlsx file, using the OpenXML libraries:

http://mikesknowledgebase.com/pages/CSharp/ExportToExcel.htm

Full source code is provided - free of charge - along with instructions, and a demo application.

After adding this class to your application, you can export your DataSet to Excel in just one line of code:

CreateExcelFile.CreateExcelDocument(myDataSet, "C:\\Sample.xlsx");

It doesn't get much simpler than that...

And it doesn't even require Excel to be present on your server.


(1) This seems a bit misleading, as you are asking for a donation to get all of the features. - user604613
(2) That's partly true: The completely free version will generate a perfect .xlsx file for you, and all source code is provided. If you donate $10 or more to one of those two charities (of which I receive absolutely nothing), then you get a "better" version showing how to do formatting, dates, etc. Given the cost of third-party products, I reckon donating $10 to a good cause instead is well worth it ! - Mike Gledhill
12
[+29] [2008-09-30 01:16:40] Sam Warwick

You could consider creating your files using the XML Spreadsheet 2003 [1] format. This is a simple XML format using a well documented schema [2].

[1] https://en.wikipedia.org/wiki/Microsoft_Office_XML_formats#Excel_XML_Spreadsheet_example
[2] https://learn.microsoft.com/en-us/previous-versions/office/developer/office-xp/aa140066(v=office.10)#odc_xmlss_ss:Workbook

13
[+25] [2008-09-29 22:48:00] ManiacZX

You may want to take a look at GemBox.Spreadsheet [1].

They have a free version with all features but limited to 150 rows per sheet and 5 sheets per workbook, if that falls within your needs.

I haven't had need to use it myself yet, but does look interesting.

[1] https://www.gemboxsoftware.com/spreadsheet/free-version

I don't think an answer recommending a paid product to solve the problem actually solves this problem. - Niels Abildgaard
14
[+24] [2016-10-07 18:03:31] Davis Jebaraj

Syncfusion Essential XlsIO [1] can do this. It has no dependency on Microsoft office and also has specific support for different platforms.

Code sample:

//Creates a new instance for ExcelEngine.
ExcelEngine excelEngine = new ExcelEngine();
//Loads or open an existing workbook through Open method of IWorkbooks
IWorkbook workbook = excelEngine.Excel.Workbooks.Open(fileName);
//To-Do some manipulation|
//To-Do some manipulation
//Set the version of the workbook.
workbook.Version = ExcelVersion.Excel2013;
//Save the workbook in file system as xlsx format
workbook.SaveAs(outputFileName);

The whole suite of controls is available for free through the community license [6] program if you qualify (less than 1 million USD in revenue). Note: I work for Syncfusion.

[1] https://www.syncfusion.com/products/file-formats/xlsio
[2] https://help.syncfusion.com/file-formats/xlsio/asp-net
[3] https://help.syncfusion.com/file-formats/xlsio/asp-net-mvc
[4] https://help.syncfusion.com/file-formats/xlsio/uwp
[5] https://help.syncfusion.com/file-formats/xlsio/xamarin
[6] https://www.syncfusion.com/products/communitylicense

Syncfusion Not free - Kiquenet
syncfusion.com/sales/communitylicense COMMUNITY LICENSE Get Our Entire Product Line for Free, Companies and individuals with less than $1 million USD in annual gross revenue and 5 or fewer developers. Note: An entity or organization may not have ever received more than $3,000,000 USD in capital from an outside source, such as private equity or venture capital, in order to be eligible for the Community License.. No credit card required. - Ignotus
15
[+21] [2015-07-23 07:55:17] Vihana Kewalramani

I have written a simple code to export dataset to excel without using excel object by using System.IO.StreamWriter.

Below is the code which will read all tables from dataset and write them to sheets one by one. I took help from this article [1].

public static void exportToExcel(DataSet source, string fileName)
{
        const string endExcelXML = "</Workbook>";
        const string startExcelXML = "<xml version>\r\n<Workbook " +
                 "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
                 " xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
                 "xmlns:x=\"urn:schemas-    microsoft-com:office:" +
                 "excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
                 "office:spreadsheet\">\r\n <Styles>\r\n " +
                 "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
                 "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
                 "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
                 "\r\n <Protection/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"BoldColumn\">\r\n <Font " +
                 "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
                 "<Style     ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
                 " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"Decimal\">\r\n <NumberFormat " +
                 "ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
                 "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
                 "ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
                 "</Styles>\r\n ";
        System.IO.StreamWriter excelDoc = null;
        excelDoc = new System.IO.StreamWriter(fileName);

        int sheetCount = 1;
        excelDoc.Write(startExcelXML);
        foreach (DataTable table in source.Tables)
        {
            int rowCount = 0;
            excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
            excelDoc.Write("<Table>");
            excelDoc.Write("<Row>");
            for (int x = 0; x < table.Columns.Count; x++)
            {
                excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
                excelDoc.Write(table.Columns[x].ColumnName);
                excelDoc.Write("</Data></Cell>");
            }
            excelDoc.Write("</Row>");
            foreach (DataRow x in table.Rows)
            {
                rowCount++;
                //if the number of rows is > 64000 create a new page to continue output
                if (rowCount == 64000)
                {
                    rowCount = 0;
                    sheetCount++;
                    excelDoc.Write("</Table>");
                    excelDoc.Write(" </Worksheet>");
                    excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
                    excelDoc.Write("<Table>");
                }
                excelDoc.Write("<Row>"); //ID=" + rowCount + "
                for (int y = 0; y < table.Columns.Count; y++)
                {
                    System.Type rowType;
                    rowType = x[y].GetType();
                    switch (rowType.ToString())
                    {
                        case "System.String":
                            string XMLstring = x[y].ToString();
                            XMLstring = XMLstring.Trim();
                            XMLstring = XMLstring.Replace("&", "&");
                            XMLstring = XMLstring.Replace(">", ">");
                            XMLstring = XMLstring.Replace("<", "<");
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                           "<Data ss:Type=\"String\">");
                            excelDoc.Write(XMLstring);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DateTime":
                            //Excel has a specific Date Format of YYYY-MM-DD followed by  
                            //the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
                            //The Following Code puts the date stored in XMLDate 
                            //to the format above
                            DateTime XMLDate = (DateTime)x[y];
                            string XMLDatetoString = ""; //Excel Converted Date
                            XMLDatetoString = XMLDate.Year.ToString() +
                                 "-" +
                                 (XMLDate.Month < 10 ? "0" +
                                 XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
                                 "-" +
                                 (XMLDate.Day < 10 ? "0" +
                                 XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
                                 "T" +
                                 (XMLDate.Hour < 10 ? "0" +
                                 XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
                                 ":" +
                                 (XMLDate.Minute < 10 ? "0" +
                                 XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
                                 ":" +
                                 (XMLDate.Second < 10 ? "0" +
                                 XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
                                 ".000";
                            excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
                                         "<Data ss:Type=\"DateTime\">");
                            excelDoc.Write(XMLDatetoString);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Boolean":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                        "<Data ss:Type=\"String\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Int16":
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
                                    "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Decimal":
                        case "System.Double":
                            excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
                                  "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DBNull":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                  "<Data ss:Type=\"String\">");
                            excelDoc.Write("");
                            excelDoc.Write("</Data></Cell>");
                            break;
                        default:
                            throw (new Exception(rowType.ToString() + " not handled."));
                    }
                }
                excelDoc.Write("</Row>");
            }
            excelDoc.Write("</Table>");
            excelDoc.Write(" </Worksheet>");
            sheetCount++;
        }


        excelDoc.Write(endExcelXML);
        excelDoc.Close();
    }
[1] https://www.codeproject.com/Articles/9380/Export-a-DataSet-to-Microsoft-Excel-without-the-us

(1) Like the article says though, that's XML that Excel will read rather than actually being an XLS file, which means that it might only work in Excel and not other programs that read spreadsheets. But it's probably better than the equivalent HTML table answers here! - Rup
Supports xlsx ? OpenXML ? - Kiquenet
The type it's Open XML but you can only write a .xls file and works perfectly. Take care with the blank spaces in the tags. Use my code refactored below. - Mauricio Kenny
16
[+19] [2008-11-24 08:22:41] biozinc

The various Office 2003 XML libraries avaliable work pretty well for smaller excel files. However, I find the sheer size of a large workbook saved in the XML format to be a problem. For example, a workbook I work with that would be 40MB in the new (and admittedly more tightly packed) XLSX format becomes a 360MB XML file.

As far as my research has taken me, there are two commercial packages that allow output to the older binary file formats. They are:

Neither are cheap (500USD and 800USD respectively, I think). but both work independant of Excel itself.

What I would be curious about is the Excel output module for the likes of OpenOffice.org. I wonder if they can be ported from Java to .Net.

[1] https://www.gemboxsoftware.com/
[2] http://www.componentone.com/SuperProducts/ExcelNET/

This one works on both .net and java,and is not expensive. SmartXLS smartxls.com - liya
17
[+18] [2015-12-02 13:30:28] Sachin Dhir

OpenXML is also a good alternative that helps avoid installing MS Excel on Server.The Open XML SDK 2.0 provided by Microsoft simplifies the task of manipulating Open XML packages and the underlying Open XML schema elements within a package. The Open XML Application Programming Interface (API) encapsulates many common tasks that developers perform on Open XML packages.

Check this out OpenXML: Alternative that helps avoid installing MS Excel on Server [1]

[1] http://technowide.net/2015/11/03/openxml-alternative-helps-avoid-ms-excel-server/

18
[+17] [2009-02-15 08:12:37] EMP

I've just recently used FlexCel.NET [1] and found it to be an excellent library! I don't say that about too many software products. No point in giving the whole sales pitch here, you can read all the features on their website.

It is a commercial product, but you get the full source if you buy it. So I suppose you could compile it into your assembly if you really wanted to. Otherwise it's just one extra assembly to xcopy - no configuration or installation or anything like that.

I don't think you'll find any way to do this without third-party libraries as .NET framework, obviously, does not have built in support for it and OLE Automation is just a whole world of pain.

[1] https://www.tmssoftware.com/site/flexcelnet.asp

I don't think recommending a paid solution really explains how to solve this problem. - Niels Abildgaard
19
[+17] [2009-11-10 05:05:23] Dimi Takis

Well,

you can also use a third party library like Aspose [1].

This library has the benefit that it does not require Excel to be installed on your machine which would be ideal in your case.

[1] http://aspose.com

To be more precise, you can use Aspose.Cells for .NET in order to create Excel (XLS, XLSX) files in your .NET application. - Shahzad Latif
(11) Yes you can, if you don't mind paying a minimum license fee of $999. Try the MikesKnowledgeBase library... which is $999 cheaper than this !! - Mike Gledhill
I don't think suggesting a paid product answers this question. - Niels Abildgaard
20
[+16] [2008-09-30 03:53:10] Aaron Powell

I agree about generating XML Spreadsheets, here's an example on how to do it for C# 3 (everyone just blogs about it in VB 9 :P) http://www.aaron-powell.com/linq-to-xml-to-excel


21
[+15] [2011-08-23 16:52:27] Eisbaer

Just want to add another reference to a third party solution that directly addresses your issue: http://www.officewriter.com

(Disclaimer: I work for SoftArtisans, the company that makes OfficeWriter)


22
[+14] [2011-04-28 10:40:05] Gaurav
public class GridViewExportUtil
{
    public static void Export(string fileName, GridView gv)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader(
            "content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";

        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                //  Create a form to contain the grid
                Table table = new Table();

                //  add the header row to the table
                if (gv.HeaderRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
                    table.Rows.Add(gv.HeaderRow);
                }

                //  add each of the data rows to the table
                foreach (GridViewRow row in gv.Rows)
                {
                    GridViewExportUtil.PrepareControlForExport(row);
                    table.Rows.Add(row);
                }

                //  add the footer row to the table
                if (gv.FooterRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.FooterRow);
                    table.Rows.Add(gv.FooterRow);
                }

                //  render the table into the htmlwriter
                table.RenderControl(htw);

                //  render the htmlwriter into the response
                HttpContext.Current.Response.Write(sw.ToString());
                HttpContext.Current.Response.End();
            }
        }
    }

    /// <summary>
    /// Replace any of the contained controls with literals
    /// </summary>
    /// <param name="control"></param>
    private static void PrepareControlForExport(Control control)
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control current = control.Controls[i];
            if (current is LinkButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
            }
            else if (current is ImageButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
            }
            else if (current is HyperLink)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
            }
            else if (current is DropDownList)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
            }
            else if (current is CheckBox)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
            }

            if (current.HasControls())
            {
                GridViewExportUtil.PrepareControlForExport(current);
            }
        }
    }
}

Hi this solution is to export your grid view to your excel file it might help you out


(7) No, this generates HTML marked as an Excel file rather than a true Excel file. Yes, Excel itself will open that OK but other programs that consume spreadsheets - including Microsoft's free Excel viewer, for example - won't accept it. You'd do better to create a real Excel file using one of the libraries here. - Rup
You should also use System.Net.Mime.ContentDisposition to generate the content-disposition header text rather than a string append - that'll cope with filenames that contains spaces etc. correctly. - Rup
GridViewExportUtil only for Web. And for Windows Forms, WPF, Console, Service Windows, Unit Test or Addin ? - Kiquenet
23
[+13] [2010-12-03 19:53:12] user529824

You can create nicely formatted Excel files using this library: http://officehelper.codeplex.com/documentation
See below sample:

using (ExcelHelper helper = new ExcelHelper(TEMPLATE_FILE_NAME, GENERATED_FILE_NAME))
{
    helper.Direction = ExcelHelper.DirectionType.TOP_TO_DOWN;
    helper.CurrentSheetName = "Sheet1";
    helper.CurrentPosition = new CellRef("C3");

    //the template xlsx should contains the named range "header"; use the command "insert"/"name".
    helper.InsertRange("header");

    //the template xlsx should contains the named range "sample1";
    //inside this range you should have cells with these values:
    //<name> , <value> and <comment>, which will be replaced by the values from the getSample()
    CellRangeTemplate sample1 = helper.CreateCellRangeTemplate("sample1", new List<string> {"name", "value", "comment"}); 
    helper.InsertRange(sample1, getSample());

    //you could use here other named ranges to insert new cells and call InsertRange as many times you want, 
    //it will be copied one after another;
    //even you can change direction or the current cell/sheet before you insert

    //typically you put all your "template ranges" (the names) on the same sheet and then you just delete it
    helper.DeleteSheet("Sheet3");
}        

where sample look like this:

private IEnumerable<List<object>> getSample()
{
    var random = new Random();

    for (int loop = 0; loop < 3000; loop++)
    {
        yield return new List<object> {"test", DateTime.Now.AddDays(random.NextDouble()*100 - 50), loop};
    }
}

24
[+13] [2011-02-16 11:47:30] Simen S

Some 3rd party component vendors like Infragistics or Syncfusion provide very good Excel export capabilities that do not require Microsoft Excel to be installed.

Since these vendors also provide advanced UI grid components, these components are particularly handy if you want the style and layout of an excel export to mimic the current state of a grid in the user interface of your application.

If your export is intended to be executed server side with emphasis on the data to be exported and with no link to the UI, then I would go for one of the free open source options (e.g. ExcelLibrary).

I have previously been involved with projects that attempted to use server side automation on the Microsoft Office suite. Based on this experience I would strongly recommend against that approach.


25
[+13] [2017-02-27 23:30:08] Taterhead

The simplest and fastest way to create an Excel file from C# is to use the Open XML Productivity Tool. The Open XML Productivity Tool comes with the Open XML SDK installation. The tool reverse engineers any Excel file into C# code. The C# code can then be used to re-generate that file.

An overview of the process involved is:

  1. Install the Open XML SDK with the tool.
  2. Create an Excel file using the latest Excel client with desired look. Name it DesiredLook.xlsx.
  3. With the tool open DesiredLook.xlsx and click the Reflect Code button near the top. enter image description here
  4. The C# code for your file will be generated in the right pane of the tool. Add this to your C# solution and generate files with that desired look.

As a bonus, this method works for any Word and PowerPoint files. As the C# developer, you will then make changes to the code to fit your needs.

I have developed a simple WPF app on github [1] which will run on Windows for this purpose. There is a placeholder class called GeneratedClass where you can paste the generated code. If you go back one version of the file, it will generate an excel file like this:

enter image description here

[1] https://github.com/thomasbtatum/GenerateAnyExcelFileWithCSharp

(1) I haven't tried this Open XML SDK solution yet but Wow, I will definitely check it out. I've worked with tools like this for many years and didn't know about this one. I've published my own simple FOSS for converting files to XLSX with .NET: github.com/TonyGravagno/NebulaXConvert - TonyG
26
[+12] [2008-09-29 22:39:50] MagicKat

IKVM [1] + POI [2]

Or, you could use the Interop ...

[1] http://www.ikvm.net/
[2] http://poi.apache.org/

27
[+12] [2008-09-30 01:39:05] Ryan Lundy

Here's a way to do it with LINQ to XML, complete with sample code:

Quickly Import and Export Excel Data with LINQ to XML [1]

It's a little complex, since you have to import namespaces and so forth, but it does let you avoid any external dependencies.

(Also, of course, it's VB .NET, not C#, but you can always isolate the VB .NET stuff in its own project to use XML Literals, and do everything else in C#.)

[1] http://blogs.msdn.com/bethmassi/archive/2007/10/30/quickly-import-and-export-excel-data-with-linq-to-xml.aspx

28
[+8] [2008-09-30 00:53:38] Nick

The Java open source solution is Apache POI [1]. Maybe there is a way to setup interop here, but I don't know enough about Java to answer that.

When I explored this problem I ended up using the Interop assemblies.

[1] https://poi.apache.org/

29
[+7] [2008-11-04 20:15:11] Stefan Koelle

Have you ever tried sylk?

We used to generate excelsheets in classic asp as sylk and right now we're searching for an excelgenerater too.

The advantages for sylk are, you can format the cells.


30
[+6] [2010-07-09 19:21:26] ScaleOvenStove

You can just write it out to XML using the Excel XML format and name it with .XLS extension and it will open with excel. You can control all the formatting (bold, widths, etc) in your XML file heading.

There is an example XML from Wikipedia [1].

[1] https://en.wikipedia.org/wiki/Microsoft_Office_XML_formats#Excel_XML_Spreadsheet_example

When I try to rename it to xls, I got this warning message: The file format and extension of 'XXx.xls' don't match. The file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway? - enb141
31
[+6] [2022-09-30 16:05:26] Fabian

I found another library that does it without much dependencies: MiniExcel [1].

You can create a DataSet with DataTables as spreadsheets (the name of the table being the name of the spreadsheet) and save it to .xlsx file by

using var stream = File.Create(filePath);
stream.SaveAs(dataSet);

or

MiniExcel.SaveAs(filePath, dataSet);

It offers also reading of Excel files and does support reading and writing of CSV files.

[1] https://github.com/mini-software/MiniExcel

32
[+5] [2009-10-22 15:21:25] community_owned

I also vote for GemBox.Spreadsheet [1].

Very fast and easy to use, with tons of examples on their site.

Took my reporting tasks on a whole new level of execution speed.

[1] https://www.gemboxsoftware.com/spreadsheet

Free version limited: Maximum number of rows per sheet is 150. - Kiquenet
33
[+5] [2017-12-07 20:40:09] AlexDev

One really easy option which is often overlooked is to create a .rdlc report using Microsoft Reporting [1] and export it to excel format. You can design it in visual studio and generate the file using:

localReport.Render("EXCELOPENXML", null, ((name, ext, encoding, mimeType, willSeek) => stream = new FileStream(name, FileMode.CreateNew)), out warnings);

You can also export it do .doc or .pdf, using "WORDOPENXML" and "PDF" respectively, and it's supported on many different platforms such as ASP.NET and SSRS.

It's much easier to make changes in a visual designer where you can see the results, and trust me, once you start grouping data, formatting group headers, adding new sections, you don't want to mess with dozens of XML nodes.

[1] https://msdn.microsoft.com/en-us/library/bb885185.aspx?f=255&MSPPError=-2147217396

full source code sample ? rdlc issues memory in ASP.NET travis.io/blog/2014/10/27/rdlc-performance-issues-dotnet45 and stackoverflow.com/questions/33436607/… - Kiquenet
34
[+5] [2019-12-20 19:02:46] Roman.Pavelko

You can try my SwiftExcel [1] library. This library writes directly to the file, so it is very efficient. For example you can write 100k rows in few seconds without any memory usage.

Here is a simple example of usage:

using (var ew = new ExcelWriter("C:\\temp\\test.xlsx"))
{
    for (var row = 1; row <= 10; row++)
    {
        for (var col = 1; col <= 5; col++)
        {
            ew.Write($"row:{row}-col:{col}", col, row);
        }
    }
}
[1] https://github.com/RomanPavelko/SwiftExcel

35
[+3] [2011-02-09 10:39:33] Craig Mc

http://www.codeproject.com/KB/cs/Excel_and_C_.aspx <= why not just use the built in power of windows, just install office on the server, any application that you install can be automated.

So much easier just use the native methods.

If it installed you can use it, this is the most awesome and under used feature in windows it was Dubbed COM back in the good old days, and it saves you tons of time and pain.

Or even easier just use the ref lib MS supplies - http://csharp.net-informations.com/excel/csharp-create-excel.htm


Why is the second way easier? Isn't it the same (adding the native object library to your project)? Do you need to have Excel installed to get this object library working? - Slauma
(7) Microsoft does not recommend or support Office Automation from non-interactive applications such as ASP.NET. See support.microsoft.com/kb/257757 - TrueWill
Excel is quite unreliable & slow when it comes to Automation. - Leslie Godwin
36
[+3] [2019-12-05 21:14:52] Michael Mainer

How to create an Excel (.xslx) file using C# on OneDrive without installing Microsoft Office

The Microsoft Graph API [1] provides File and Excel APIs for creating and modifying Excel files stored in OneDrive for both enterprise and consumer accounts. The Microsoft.Graph [2] NuGet package provides many interfaces for working with the File and Excel APIs.

{
  Name = "myExcelFile.xslx",
  File = new Microsoft.Graph.File()
};

// Create an empty file in the user's OneDrive.
var excelWorkbookDriveItem = await graphClient.Me.Drive.Root.Children.Request().AddAsync(excelWorkbook);

// Add the contents of a template Excel file.
DriveItem excelDriveItem;
using (Stream ms = ResourceHelper.GetResourceAsStream(ResourceHelper.ExcelTestResource))
{
    //Upload content to the file. ExcelTestResource is an empty template Excel file.
    //https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/item_uploadcontent
    excelDriveItem = await graphClient.Me.Drive.Items[excelWorkbookDriveItem.Id].Content.Request().PutAsync<DriveItem>(ms);
}

At this point, you now have an Excel file created in the user (enterprise or consumer) or group's OneDrive. You can now use the Excel APIs [3] to make changes to the Excel file without using Excel and without needing to understand the Excel XML format.

[1] https://developer.microsoft.com/en-us/graph
[2] https://www.nuget.org/packages/Microsoft.Graph
[3] https://learn.microsoft.com/en-us/graph/api/resources/excel?view=graph-rest-1.0

full sample? what is graphClient ? ResourceHelper? ExcelTestResource is an empty template Excel file ? - Kiquenet
@Kiquenet graphClient is found in the Microsoft.Graph NuGet package. Yes, ExcelTestResource is an empty Excel file. ResourceHelper gets the empty Excel file stream. Here's a sample that uses the GraphServiceClient (graphClient in this example): github.com/microsoftgraph/dotnetcore-console-sample. There isn't an example of using the Excel API in it. - Michael Mainer
37
[+3] [2020-06-30 11:49:43] Miguel Tomás

You can install OpenXml nuget package on Visual Studio. Here is a bit of code to export a data table to an excel file:

Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet

Public Class ExportExcelClass
    Public Sub New()

    End Sub

    Public Sub ExportDataTable(ByVal table As DataTable, ByVal exportFile As String)
        ' Create a spreadsheet document by supplying the filepath.
        ' By default, AutoSave = true, Editable = true, and Type = xlsx.
        Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Create(exportFile, SpreadsheetDocumentType.Workbook)

        ' Add a WorkbookPart to the document.
        Dim workbook As WorkbookPart = spreadsheetDocument.AddWorkbookPart
        workbook.Workbook = New Workbook

        ' Add a WorksheetPart to the WorkbookPart.
        Dim Worksheet As WorksheetPart = workbook.AddNewPart(Of WorksheetPart)()
        Worksheet.Worksheet = New Worksheet(New SheetData())

        ' Add Sheets to the Workbook.
        Dim sheets As Sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())

        Dim data As SheetData = Worksheet.Worksheet.GetFirstChild(Of SheetData)()
        Dim Header As Row = New Row()
        Header.RowIndex = CType(1, UInt32)

        For Each column As DataColumn In table.Columns
            Dim headerCell As Cell = createTextCell(table.Columns.IndexOf(column) + 1, 1, column.ColumnName)
            Header.AppendChild(headerCell)
        Next

        data.AppendChild(Header)

        Dim contentRow As DataRow
        For i As Integer = 0 To table.Rows.Count - 1
            contentRow = table.Rows(i)
            data.AppendChild(createContentRow(contentRow, i + 2))
        Next

    End Sub

    Private Function createTextCell(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal cellValue As Object) As Cell
        Dim cell As Cell = New Cell()
        cell.DataType = CellValues.InlineString

        cell.CellReference = getColumnName(columnIndex) + rowIndex.ToString

        Dim inlineString As InlineString = New InlineString()
        Dim t As Text = New Text()
        t.Text = cellValue.ToString()
        inlineString.AppendChild(t)
        cell.AppendChild(inlineString)
        Return cell
    End Function

    Private Function createContentRow(ByVal dataRow As DataRow, ByVal rowIndex As Integer) As Row
        Dim row As Row = New Row With {
            .rowIndex = CType(rowIndex, UInt32)
        }

        For i As Integer = 0 To dataRow.Table.Columns.Count - 1
            Dim dataCell As Cell = createTextCell(i + 1, rowIndex, dataRow(i))
            row.AppendChild(dataCell)
        Next

        Return row
    End Function

    Private Function getColumnName(ByVal columnIndex As Integer) As String
        Dim dividend As Integer = columnIndex
        Dim columnName As String = String.Empty
        Dim modifier As Integer

        While dividend > 0
            modifier = (dividend - 1) Mod 26
            columnName = Convert.ToChar(65 + modifier).ToString() & columnName
            dividend = CInt(((dividend - modifier) / 26))
        End While

        Return columnName
    End Function
End Class

spreadsheetDocument.Create will be SpreadsheetDocument.Create ? - Kiquenet
38
[+3] [2020-12-08 20:25:16] Mauricio Kenny

I recode again the code and now you can create an .xls file, later you can convert to Excel 2003 Open XML Format.

private static void exportToExcel(DataSet source, string fileName)
    {
        // Documentacion en:
        // https://en.wikipedia.org/wiki/Microsoft_Office_XML_formats
        // https://answers.microsoft.com/en-us/msoffice/forum/all/how-to-save-office-ms-xml-as-xlsx-file/4a77dae5-6855-457d-8359-e7b537beb1db
        // https://riptutorial.com/es/openxml

        const string startExcelXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"+
                 "<?mso-application progid=\"Excel.Sheet\"?>\r\n" +
                 "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
                 "xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
                 "xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\r\n " +
                 "xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n " +
                 "xmlns:html=\"http://www.w3.org/TR/REC-html40\">\r\n " +
                 "xmlns:html=\"https://www.w3.org/TR/html401/\">\r\n " +

                 "<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n " +
                 "  <Version>16.00</Version>\r\n " +
                 "</DocumentProperties>\r\n " +
                 " <OfficeDocumentSettings xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n " +
                 "  <AllowPNG/>\r\n " +
                 " </OfficeDocumentSettings>\r\n " +

                 " <ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n " +
                 "  <WindowHeight>9750</WindowHeight>\r\n " +
                 "  <WindowWidth>24000</WindowWidth>\r\n " +
                 "  <WindowTopX>0</WindowTopX>\r\n " +
                 "  <WindowTopY>0</WindowTopY>\r\n " +
                 "  <RefModeR1C1/>\r\n " +
                 "  <ProtectStructure>False</ProtectStructure>\r\n " +
                 "  <ProtectWindows>False</ProtectWindows>\r\n " +
                 " </ExcelWorkbook>\r\n " +

                 "<Styles>\r\n " +
                 "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
                 "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
                 "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
                 "\r\n <Protection/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"BoldColumn\">\r\n <Font " +
                 "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
                 " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"Decimal\">\r\n <NumberFormat " +
                 "ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"Integer\">\r\n <NumberFormat/>" +
                 "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
                 "ss:Format=\"dd/mm/yyyy;@\"/>\r\n </Style>\r\n " +
                 "</Styles>\r\n ";
        System.IO.StreamWriter excelDoc = null;
        excelDoc = new System.IO.StreamWriter(fileName,false);

        int sheetCount = 1;
        excelDoc.Write(startExcelXML);
        foreach (DataTable table in source.Tables)
        {
            int rowCount = 0;
            excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
            excelDoc.Write("<Table>");
            excelDoc.Write("<Row>");
            for (int x = 0; x < table.Columns.Count; x++)
            {
                excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
                excelDoc.Write(table.Columns[x].ColumnName);
                excelDoc.Write("</Data></Cell>");
            }
            excelDoc.Write("</Row>");
            foreach (DataRow x in table.Rows)
            {
                rowCount++;
                //if the number of rows is > 64000 create a new page to continue output
                if (rowCount == 1048576)
                {
                    rowCount = 0;
                    sheetCount++;
                    excelDoc.Write("</Table>");
                    excelDoc.Write(" </Worksheet>");
                    excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
                    excelDoc.Write("<Table>");
                }
                excelDoc.Write("<Row>"); //ID=" + rowCount + "
                for (int y = 0; y < table.Columns.Count; y++)
                {
                    System.Type rowType;
                    rowType = x[y].GetType();
                    switch (rowType.ToString())
                    {
                        case "System.String":
                            string XMLstring = x[y].ToString();
                            XMLstring = XMLstring.Trim();
                            XMLstring = XMLstring.Replace("&", "&");
                            XMLstring = XMLstring.Replace(">", ">");
                            XMLstring = XMLstring.Replace("<", "<");
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                           "<Data ss:Type=\"String\">");
                            excelDoc.Write(XMLstring);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DateTime":
                            //Excel has a specific Date Format of YYYY-MM-DD followed by  
                            //the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
                            //The Following Code puts the date stored in XMLDate 
                            //to the format above
                            DateTime XMLDate = (DateTime)x[y];
                            string XMLDatetoString = ""; //Excel Converted Date
                            XMLDatetoString = XMLDate.Year.ToString() +
                                 "-" +
                                 (XMLDate.Month < 10 ? "0" +
                                 XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
                                 "-" +
                                 (XMLDate.Day < 10 ? "0" +
                                 XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
                                 "T" +
                                 (XMLDate.Hour < 10 ? "0" +
                                 XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
                                 ":" +
                                 (XMLDate.Minute < 10 ? "0" +
                                 XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
                                 ":" +
                                 (XMLDate.Second < 10 ? "0" +
                                 XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
                                 ".000";
                            excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
                                         "<Data ss:Type=\"DateTime\">");
                            excelDoc.Write(XMLDatetoString);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Boolean":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                        "<Data ss:Type=\"String\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Int16":
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
                                    "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Decimal":
                        case "System.Double":
                            excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
                                  "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DBNull":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                  "<Data ss:Type=\"String\">");
                            excelDoc.Write("");
                            excelDoc.Write("</Data></Cell>");
                            break;
                        default:
                            throw (new Exception(rowType.ToString() + " not handled."));
                    }
                }
                excelDoc.Write("</Row>");
            }
            excelDoc.Write("</Table>");
            excelDoc.Write("</Worksheet>");               
            sheetCount++;
        }

        const string endExcelOptions1 = "\r\n<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n" +
            "<Selected/>\r\n" +
            "<ProtectObjects>False</ProtectObjects>\r\n" +
            "<ProtectScenarios>False</ProtectScenarios>\r\n" +
            "</WorksheetOptions>\r\n";

        excelDoc.Write(endExcelOptions1);
        excelDoc.Write("</Workbook>");
        excelDoc.Close();
    }

File opens but excel gives an error "The file format an extension doesn not match" - user1034912
39
[+3] [2021-11-12 15:33:15] MT1

Here is the simplest way to create an Excel file.

Excel files with extension .xlsx are compressed folders containing .XML files - but complicated.

First create the folder structure as follows -

public class CreateFileOrFolder
{
    static void Main()
    {
        //
        // https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-create-a-file-or-folder
        //
        // https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-write-to-a-text-file
        //
        // .NET Framework 4.7.2
        //
        // Specify a name for your top-level folder.
        string folderName = @"C:\Users\david\Desktop\Book3";

        // To create a string that specifies the path to a subfolder under your
        // top-level folder, add a name for the subfolder to folderName.

        string pathString = System.IO.Path.Combine(folderName, "_rels");
        System.IO.Directory.CreateDirectory(pathString);
        pathString = System.IO.Path.Combine(folderName, "docProps");
        System.IO.Directory.CreateDirectory(pathString);
        pathString = System.IO.Path.Combine(folderName, "xl");
        System.IO.Directory.CreateDirectory(pathString);

        string subPathString = System.IO.Path.Combine(pathString, "_rels");
        System.IO.Directory.CreateDirectory(subPathString);
        subPathString = System.IO.Path.Combine(pathString, "theme");
        System.IO.Directory.CreateDirectory(subPathString);
        subPathString = System.IO.Path.Combine(pathString, "worksheets");
        System.IO.Directory.CreateDirectory(subPathString);
        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}

Next, create text files to hold the XML needed to describe the Excel spreadsheet.

namespace MakeFiles3
{
    class Program
    {
        static void Main(string[] args)
        {
            //
            // https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-write-to-a-text-file
            //
            // .NET Framework 4.7.2
            //
            string fileName = @"C:\Users\david\Desktop\Book3\_rels\.rels";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\docProps\app.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\docProps\core.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\xl\_rels\workbook.xml.rels";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\xl\theme\theme1.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\xl\worksheets\sheet1.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\xl\styles.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\xl\workbook.xml";
            fnWriteFile(fileName);
            fileName = @"C:\Users\david\Desktop\Book3\[Content_Types].xml";
            fnWriteFile(fileName);
            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();

            bool fnWriteFile(string strFilePath)
            {
                if (!System.IO.File.Exists(strFilePath))
                {
                    using (System.IO.FileStream fs = System.IO.File.Create(strFilePath))
                    {
                        return true;
                    }
                }
                else
                {
                    System.Console.WriteLine("File \"{0}\" already exists.", strFilePath);
                    return false;
                }
            }
        }
    }
}

Next populate the text files with XML.

The XML required is fairly verbose so you may need to use this github repository.

https://github.com/DaveTallett26/MakeFiles4/blob/master/MakeFiles4/Program.cs

//
// https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
// .NET Framework 4.7.2
//
using System.IO;

namespace MakeFiles4
{
    class Program
    {
        static void Main(string[] args)
        {
            string xContents = @"a";
            string xFilename = @"a";
            xFilename = @"C:\Users\david\Desktop\Book3\[Content_Types].xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types""><Default Extension=""rels"" ContentType=""application/vnd.openxmlformats-package.relationships+xml""/><Default Extension=""xml"" ContentType=""application/xml""/><Override PartName=""/xl/workbook.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml""/><Override PartName=""/xl/worksheets/sheet1.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml""/><Override PartName=""/xl/theme/theme1.xml"" ContentType=""application/vnd.openxmlformats-officedocument.theme+xml""/><Override PartName=""/xl/styles.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml""/><Override PartName=""/docProps/core.xml"" ContentType=""application/vnd.openxmlformats-package.core-properties+xml""/><Override PartName=""/docProps/app.xml"" ContentType=""application/vnd.openxmlformats-officedocument.extended-properties+xml""/></Types>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\_rels\.rels";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships""><Relationship Id=""rId3"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"" Target=""docProps/app.xml""/><Relationship Id=""rId2"" Type=""http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"" Target=""docProps/core.xml""/><Relationship Id=""rId1"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"" Target=""xl/workbook.xml""/></Relationships>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\docProps\app.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Properties xmlns=""http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"" xmlns:vt=""http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes""><Application>Microsoft Excel</Application><DocSecurity>0</DocSecurity><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size=""2"" baseType=""variant""><vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size=""1"" baseType=""lpstr""><vt:lpstr>Sheet1</vt:lpstr></vt:vector></TitlesOfParts><Company></Company><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0300</AppVersion></Properties>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\docProps\core.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><cp:coreProperties xmlns:cp=""http://schemas.openxmlformats.org/package/2006/metadata/core-properties"" xmlns:dc=""http://purl.org/dc/elements/1.1/"" xmlns:dcterms=""http://purl.org/dc/terms/"" xmlns:dcmitype=""http://purl.org/dc/dcmitype/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""><dc:creator>David Tallett</dc:creator><cp:lastModifiedBy>David Tallett</cp:lastModifiedBy><dcterms:created xsi:type=""dcterms:W3CDTF"">2021-10-26T15:47:15Z</dcterms:created><dcterms:modified xsi:type=""dcterms:W3CDTF"">2021-10-26T15:47:35Z</dcterms:modified></cp:coreProperties>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\xl\styles.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><styleSheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x14ac x16r2 xr"" xmlns:x14ac=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"" xmlns:x16r2=""http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"" xmlns:xr=""http://schemas.microsoft.com/office/spreadsheetml/2014/revision""><fonts count=""1"" x14ac:knownFonts=""1""><font><sz val=""11""/><color theme=""1""/><name val=""Calibri""/><family val=""2""/><scheme val=""minor""/></font></fonts><fills count=""2""><fill><patternFill patternType=""none""/></fill><fill><patternFill patternType=""gray125""/></fill></fills><borders count=""1""><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count=""1""><xf numFmtId=""0"" fontId=""0"" fillId=""0"" borderId=""0""/></cellStyleXfs><cellXfs count=""1""><xf numFmtId=""0"" fontId=""0"" fillId=""0"" borderId=""0"" xfId=""0""/></cellXfs><cellStyles count=""1""><cellStyle name=""Normal"" xfId=""0"" builtinId=""0""/></cellStyles><dxfs count=""0""/><tableStyles count=""0"" defaultTableStyle=""TableStyleMedium2"" defaultPivotStyle=""PivotStyleLight16""/><extLst><ext uri=""{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"" xmlns:x14=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/main""><x14:slicerStyles defaultSlicerStyle=""SlicerStyleLight1""/></ext><ext uri=""{9260A510-F301-46a8-8635-F512D64BE5F5}"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main""><x15:timelineStyles defaultTimelineStyle=""TimeSlicerStyleLight1""/></ext></extLst></styleSheet>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\xl\workbook.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><workbook xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x15 xr xr6 xr10 xr2"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"" xmlns:xr=""http://schemas.microsoft.com/office/spreadsheetml/2014/revision"" xmlns:xr6=""http://schemas.microsoft.com/office/spreadsheetml/2016/revision6"" xmlns:xr10=""http://schemas.microsoft.com/office/spreadsheetml/2016/revision10"" xmlns:xr2=""http://schemas.microsoft.com/office/spreadsheetml/2015/revision2""><fileVersion appName=""xl"" lastEdited=""7"" lowestEdited=""7"" rupBuild=""24430""/><workbookPr defaultThemeVersion=""166925""/><mc:AlternateContent xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006""><mc:Choice Requires=""x15""><x15ac:absPath url=""C:\Users\david\Desktop\"" xmlns:x15ac=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac""/></mc:Choice></mc:AlternateContent><xr:revisionPtr revIDLastSave=""0"" documentId=""8_{C633700D-2D40-49EE-8C5E-2561E28A6758}"" xr6:coauthVersionLast=""47"" xr6:coauthVersionMax=""47"" xr10:uidLastSave=""{00000000-0000-0000-0000-000000000000}""/><bookViews><workbookView xWindow=""-120"" yWindow=""-120"" windowWidth=""29040"" windowHeight=""15840"" xr2:uid=""{934C5B62-1DC1-4322-BAE8-00D615BD2FB3}""/></bookViews><sheets><sheet name=""Sheet1"" sheetId=""1"" r:id=""rId1""/></sheets><calcPr calcId=""191029""/><extLst><ext uri=""{140A7094-0E35-4892-8432-C4D2E57EDEB5}"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main""><x15:workbookPr chartTrackingRefBase=""1""/></ext><ext uri=""{B58B0392-4F1F-4190-BB64-5DF3571DCE5F}"" xmlns:xcalcf=""http://schemas.microsoft.com/office/spreadsheetml/2018/calcfeatures""><xcalcf:calcFeatures><xcalcf:feature name=""microsoft.com:RD""/><xcalcf:feature name=""microsoft.com:Single""/><xcalcf:feature name=""microsoft.com:FV""/><xcalcf:feature name=""microsoft.com:CNMTM""/><xcalcf:feature name=""microsoft.com:LET_WF""/></xcalcf:calcFeatures></ext></extLst></workbook>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\xl\_rels\workbook.xml.rels";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships""><Relationship Id=""rId3"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"" Target=""styles.xml""/><Relationship Id=""rId2"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"" Target=""theme/theme1.xml""/><Relationship Id=""rId1"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"" Target=""worksheets/sheet1.xml""/></Relationships>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\xl\theme\theme1.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><a:theme xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"" name=""Office Theme""><a:themeElements><a:clrScheme name=""Office""><a:dk1><a:sysClr val=""windowText"" lastClr=""000000""/></a:dk1><a:lt1><a:sysClr val=""window"" lastClr=""FFFFFF""/></a:lt1><a:dk2><a:srgbClr val=""44546A""/></a:dk2><a:lt2><a:srgbClr val=""E7E6E6""/></a:lt2><a:accent1><a:srgbClr val=""4472C4""/></a:accent1><a:accent2><a:srgbClr val=""ED7D31""/></a:accent2><a:accent3><a:srgbClr val=""A5A5A5""/></a:accent3><a:accent4><a:srgbClr val=""FFC000""/></a:accent4><a:accent5><a:srgbClr val=""5B9BD5""/></a:accent5><a:accent6><a:srgbClr val=""70AD47""/></a:accent6><a:hlink><a:srgbClr val=""0563C1""/></a:hlink><a:folHlink><a:srgbClr val=""954F72""/></a:folHlink></a:clrScheme><a:fontScheme name=""Office""><a:majorFont><a:latin typeface=""Calibri Light"" panose=""020F0302020204030204""/><a:ea typeface=""""/><a:cs typeface=""""/><a:font script=""Jpan"" typeface=""游ゴシック Light""/><a:font script=""Hang"" typeface=""맑은 고딕""/><a:font script=""Hans"" typeface=""等线 Light""/><a:font script=""Hant"" typeface=""新細明體""/><a:font script=""Arab"" typeface=""Times New Roman""/><a:font script=""Hebr"" typeface=""Times New Roman""/><a:font script=""Thai"" typeface=""Tahoma""/><a:font script=""Ethi"" typeface=""Nyala""/><a:font script=""Beng"" typeface=""Vrinda""/><a:font script=""Gujr"" typeface=""Shruti""/><a:font script=""Khmr"" typeface=""MoolBoran""/><a:font script=""Knda"" typeface=""Tunga""/><a:font script=""Guru"" typeface=""Raavi""/><a:font script=""Cans"" typeface=""Euphemia""/><a:font script=""Cher"" typeface=""Plantagenet Cherokee""/><a:font script=""Yiii"" typeface=""Microsoft Yi Baiti""/><a:font script=""Tibt"" typeface=""Microsoft Himalaya""/><a:font script=""Thaa"" typeface=""MV Boli""/><a:font script=""Deva"" typeface=""Mangal""/><a:font script=""Telu"" typeface=""Gautami""/><a:font script=""Taml"" typeface=""Latha""/><a:font script=""Syrc"" typeface=""Estrangelo Edessa""/><a:font script=""Orya"" typeface=""Kalinga""/><a:font script=""Mlym"" typeface=""Kartika""/><a:font script=""Laoo"" typeface=""DokChampa""/><a:font script=""Sinh"" typeface=""Iskoola Pota""/><a:font script=""Mong"" typeface=""Mongolian Baiti""/><a:font script=""Viet"" typeface=""Times New Roman""/><a:font script=""Uigh"" typeface=""Microsoft Uighur""/><a:font script=""Geor"" typeface=""Sylfaen""/><a:font script=""Armn"" typeface=""Arial""/><a:font script=""Bugi"" typeface=""Leelawadee UI""/><a:font script=""Bopo"" typeface=""Microsoft JhengHei""/><a:font script=""Java"" typeface=""Javanese Text""/><a:font script=""Lisu"" typeface=""Segoe UI""/><a:font script=""Mymr"" typeface=""Myanmar Text""/><a:font script=""Nkoo"" typeface=""Ebrima""/><a:font script=""Olck"" typeface=""Nirmala UI""/><a:font script=""Osma"" typeface=""Ebrima""/><a:font script=""Phag"" typeface=""Phagspa""/><a:font script=""Syrn"" typeface=""Estrangelo Edessa""/><a:font script=""Syrj"" typeface=""Estrangelo Edessa""/><a:font script=""Syre"" typeface=""Estrangelo Edessa""/><a:font script=""Sora"" typeface=""Nirmala UI""/><a:font script=""Tale"" typeface=""Microsoft Tai Le""/><a:font script=""Talu"" typeface=""Microsoft New Tai Lue""/><a:font script=""Tfng"" typeface=""Ebrima""/></a:majorFont><a:minorFont><a:latin typeface=""Calibri"" panose=""020F0502020204030204""/><a:ea typeface=""""/><a:cs typeface=""""/><a:font script=""Jpan"" typeface=""游ゴシック""/><a:font script=""Hang"" typeface=""맑은 고딕""/><a:font script=""Hans"" typeface=""等线""/><a:font script=""Hant"" typeface=""新細明體""/><a:font script=""Arab"" typeface=""Arial""/><a:font script=""Hebr"" typeface=""Arial""/><a:font script=""Thai"" typeface=""Tahoma""/><a:font script=""Ethi"" typeface=""Nyala""/><a:font script=""Beng"" typeface=""Vrinda""/><a:font script=""Gujr"" typeface=""Shruti""/><a:font script=""Khmr"" typeface=""DaunPenh""/><a:font script=""Knda"" typeface=""Tunga""/><a:font script=""Guru"" typeface=""Raavi""/><a:font script=""Cans"" typeface=""Euphemia""/><a:font script=""Cher"" typeface=""Plantagenet Cherokee""/><a:font script=""Yiii"" typeface=""Microsoft Yi Baiti""/><a:font script=""Tibt"" typeface=""Microsoft Himalaya""/><a:font script=""Thaa"" typeface=""MV Boli""/><a:font script=""Deva"" typeface=""Mangal""/><a:font script=""Telu"" typeface=""Gautami""/><a:font script=""Taml"" typeface=""Latha""/><a:font script=""Syrc"" typeface=""Estrangelo Edessa""/><a:font script=""Orya"" typeface=""Kalinga""/><a:font script=""Mlym"" typeface=""Kartika""/><a:font script=""Laoo"" typeface=""DokChampa""/><a:font script=""Sinh"" typeface=""Iskoola Pota""/><a:font script=""Mong"" typeface=""Mongolian Baiti""/><a:font script=""Viet"" typeface=""Arial""/><a:font script=""Uigh"" typeface=""Microsoft Uighur""/><a:font script=""Geor"" typeface=""Sylfaen""/><a:font script=""Armn"" typeface=""Arial""/><a:font script=""Bugi"" typeface=""Leelawadee UI""/><a:font script=""Bopo"" typeface=""Microsoft JhengHei""/><a:font script=""Java"" typeface=""Javanese Text""/><a:font script=""Lisu"" typeface=""Segoe UI""/><a:font script=""Mymr"" typeface=""Myanmar Text""/><a:font script=""Nkoo"" typeface=""Ebrima""/><a:font script=""Olck"" typeface=""Nirmala UI""/><a:font script=""Osma"" typeface=""Ebrima""/><a:font script=""Phag"" typeface=""Phagspa""/><a:font script=""Syrn"" typeface=""Estrangelo Edessa""/><a:font script=""Syrj"" typeface=""Estrangelo Edessa""/><a:font script=""Syre"" typeface=""Estrangelo Edessa""/><a:font script=""Sora"" typeface=""Nirmala UI""/><a:font script=""Tale"" typeface=""Microsoft Tai Le""/><a:font script=""Talu"" typeface=""Microsoft New Tai Lue""/><a:font script=""Tfng"" typeface=""Ebrima""/></a:minorFont></a:fontScheme><a:fmtScheme name=""Office""><a:fillStyleLst><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:lumMod val=""110000""/><a:satMod val=""105000""/><a:tint val=""67000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:lumMod val=""105000""/><a:satMod val=""103000""/><a:tint val=""73000""/></a:schemeClr></a:gs><a:gs pos=""100000""><a:schemeClr val=""phClr""><a:lumMod val=""105000""/><a:satMod val=""109000""/><a:tint val=""81000""/></a:schemeClr></a:gs></a:gsLst><a:lin ang=""5400000"" scaled=""0""/></a:gradFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:satMod val=""103000""/><a:lumMod val=""102000""/><a:tint val=""94000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:satMod val=""110000""/><a:lumMod val=""100000""/><a:shade val=""100000""/></a:schemeClr></a:gs><a:gs pos=""100000""><a:schemeClr val=""phClr""><a:lumMod val=""99000""/><a:satMod val=""120000""/><a:shade val=""78000""/></a:schemeClr></a:gs></a:gsLst><a:lin ang=""5400000"" scaled=""0""/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=""6350"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln><a:ln w=""12700"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln><a:ln w=""19050"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=""57150"" dist=""19050"" dir=""5400000"" algn=""ctr"" rotWithShape=""0""><a:srgbClr val=""000000""><a:alpha val=""63000""/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:solidFill><a:schemeClr val=""phClr""><a:tint val=""95000""/><a:satMod val=""170000""/></a:schemeClr></a:solidFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:tint val=""93000""/><a:satMod val=""150000""/><a:shade val=""98000""/><a:lumMod val=""102000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:tint val=""98000""/><a:satMod val=""130000""/><a:shade val=""90000""/><a:lumMod val=""103000""/></a:schemeClr></a:gs><a:gs pos=""100000""><a:schemeClr val=""phClr""><a:shade val=""63000""/><a:satMod val=""120000""/></a:schemeClr></a:gs></a:gsLst><a:lin ang=""5400000"" scaled=""0""/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/><a:extLst><a:ext uri=""{05A4C25C-085E-4340-85A3-A5531E510DB2}""><thm15:themeFamily xmlns:thm15=""http://schemas.microsoft.com/office/thememl/2012/main"" name=""Office Theme"" id=""{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}"" vid=""{4A3C46E8-61CC-4603-A589-7422A47A8E4A}""/></a:ext></a:extLst></a:theme>";
            StartExstream(xContents, xFilename);

            xFilename = @"C:\Users\david\Desktop\Book3\xl\worksheets\sheet1.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><worksheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x14ac xr xr2 xr3"" xmlns:x14ac=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"" xmlns:xr=""http://schemas.microsoft.com/office/spreadsheetml/2014/revision"" xmlns:xr2=""http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"" xmlns:xr3=""http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"" xr:uid=""{54E3D330-4E78-4755-89E0-1AADACAC4953}""><dimension ref=""A1:A3""/><sheetViews><sheetView tabSelected=""1"" workbookViewId=""0""><selection activeCell=""A4"" sqref=""A4""/></sheetView></sheetViews><sheetFormatPr defaultRowHeight=""15"" x14ac:dyDescent=""0.25""/><sheetData><row r=""1"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A1""><v>1</v></c></row><row r=""2"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A2""><v>2</v></c></row><row r=""3"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A3""><v>3</v></c></row></sheetData><pageMargins left=""0.7"" right=""0.7"" top=""0.75"" bottom=""0.75"" header=""0.3"" footer=""0.3""/></worksheet>";
            StartExstream(xContents, xFilename);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();

            bool StartExstream(string strLine, string strFileName)
            {
                // Write the string to a file.
                using (StreamWriter outputFile = new StreamWriter(strFileName))
                {
                    outputFile.WriteLine(strLine);
                    return true;
                }
            }
        }
    }
}

Finally ZIP the folder structure containing the XML -

namespace ZipFolder
// .NET Framework 4.7.2
// https://stackoverflow.com/questions/15241889/i-didnt-find-zipfile-class-in-the-system-io-compression-namespace?answertab=votes#tab-top
{
    class Program
    {
        static void Main(string[] args)
        {
            string xlPath = @"C:\Users\david\Desktop\Book3.xlsx";
            string folderPath = @"C:\Users\david\Desktop\Book3";

            System.IO.Compression.ZipFile.CreateFromDirectory(folderPath, xlPath);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

This produces an Excel file named Book3.xlsx which is valid and opens cleanly in Excel 365 on Windows 11.

The result is a very simple Excel spreadsheet but you may need to reverse engineer a more complex version. Here is the code to unzip a .xlsx file.

namespace UnZipXL
// .NET Framework 4.7.2
// https://stackoverflow.com/questions/15241889/i-didnt-find-zipfile-class-in-the-system-io-compression-namespace?answertab=votes#tab-top
{
    class Program
    {
        static void Main(string[] args)
        {
            string XLPath = @"C:\Users\david\Desktop\Book2.xlsx";
            string extractPath = @"C:\Users\david\Desktop\extract";

            System.IO.Compression.ZipFile.ExtractToDirectory(XLPath, extractPath);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

Update:

Here is a code fragment to update the Excel file. This is very simple again.

//
// https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
// .NET Framework 4.7.2
//
using System.IO;

namespace UpdateWorksheet5
{
    class Program
    {
        static void Main(string[] args)
        {
            string xContents = @"a";
            string xFilename = @"a";

            xFilename = @"C:\Users\david\Desktop\Book3\xl\worksheets\sheet1.xml";
            xContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><worksheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x14ac xr xr2 xr3"" xmlns:x14ac=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"" xmlns:xr=""http://schemas.microsoft.com/office/spreadsheetml/2014/revision"" xmlns:xr2=""http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"" xmlns:xr3=""http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"" xr:uid=""{54E3D330-4E78-4755-89E0-1AADACAC4953}""><dimension ref=""A1:A3""/><sheetViews><sheetView tabSelected=""1"" workbookViewId=""0""><selection activeCell=""A4"" sqref=""A4""/></sheetView></sheetViews><sheetFormatPr defaultRowHeight=""15"" x14ac:dyDescent=""0.25""/><sheetData><row r=""1"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A1""><v>1</v></c></row><row r=""2"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A2""><v>2</v></c></row><row r=""3"" spans=""1:1"" x14ac:dyDescent=""0.25""><c r=""A3""><v>3</v></c></row></sheetData><pageMargins left=""0.7"" right=""0.7"" top=""0.75"" bottom=""0.75"" header=""0.3"" footer=""0.3""/></worksheet>";
            xContents = xContents.Remove(941, 1).Insert(941, "0"); //  character to replace is at 942 => index 941
            StartExstream(xContents, xFilename);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();

            bool StartExstream(string strLine, string strFileName)
            {
                // Write the string to a file.
                using (StreamWriter outputFile = new StreamWriter(strFileName))
                {
                    outputFile.WriteLine(strLine);
                    return true;
                }
            }
        }
    }
}

Update 2 - This code works almost unchanged except for the folder paths on a Mac. Using Microsoft Excel Online, .NET Framework 3.1, Visual Studio 2019 for Mac, MacOS Monterey 12.1.


(3) That's the basics of the zip structure but it looks like you've only got hard-coded XML examples and that you're a long way from setting an individual cell value, say. It might be easier to start with one of the other libraries linked here that have solved all of that already. - Rup
(2) This is anything but simple. This is the worst-case scenario - Panagiotis Kanavos
(3) I didn't know that xlsx files are actually zipped folders with xml files :D thanks for the information! - Ozan Yasin Dogan
(1) Kudos for trying, but editing one value by string offset is nowhere near general enough to be useful to anyone. How would you write a function in this scheme that accepted a cell row and column and set that cell to a number? And how would you do the same for a string (which is more complicated IIRC!) - Rup
Do you have a reference? How can one learn this information? - john k
copy and paste the code into Visual Studio and run it. @johnktejik - MT1
@johnktejik If you mean an XML schema reference, this is the ISO website: iso.org/standard/71691.html - Rup
40
[+1] [2017-04-05 09:00:59] Gayan Chinthaka Dharmarathna

If you make data table or datagridview from the code you can save all data using this simple method.this method not recomended but its working 100%, even you are not install MS Excel in your computer.

try
 {
  SaveFileDialog saveFileDialog1 = new SaveFileDialog();
  saveFileDialog1.Filter = "Excel Documents (*.xls)|*.xls";
  saveFileDialog1.FileName = "Employee Details.xls";
  if (saveFileDialog1.ShowDialog() == DialogResult.OK)
  {
  string fname = saveFileDialog1.FileName;
  StreamWriter wr = new StreamWriter(fname);
  for (int i = 0; i <DataTable.Columns.Count; i++)
  {
  wr.Write(DataTable.Columns[i].ToString().ToUpper() + "\t");
  }
  wr.WriteLine();

  //write rows to excel file
  for (int i = 0; i < (DataTable.Rows.Count); i++)
  {
  for (int j = 0; j < DataTable.Columns.Count; j++)
  {
  if (DataTable.Rows[i][j] != null)
  {
  wr.Write(Convert.ToString(getallData.Rows[i][j]) + "\t");
  }
   else
   {
   wr.Write("\t");
   }
   }
   //go to next line
   wr.WriteLine();
   }
   //close file
   wr.Close();
   }
   }
   catch (Exception)
   {
    MessageBox.Show("Error Create Excel Sheet!");
   }

41
[+1] [2017-09-27 15:18:35] Vladimir Venegas

Some time ago, I created a DLL on top of NPOI. It's very simple to use it:

IList<DummyPerson> dummyPeople = new List<DummyPerson>();
//Add data to dummyPeople...
IExportEngine engine = new ExcelExportEngine();
engine.AddData(dummyPeople); 
MemoryStream memory = engine.Export();

You could read more about it on here [1].

By the way, is 100% open source. Feel free to use, edit and share ;)

[1] https://github.com/vvenegasv/exportable

42
[+1] [2018-11-05 07:46:39] Vijay Dodamani

To save xls into xlsx format, we just need to call SaveAs method from Microsoft.Office.Interop.Excel library. This method will take around 16 parameters and one of them is file format as well.

Microsoft document: Here SaveAs Method Arguments [1]

The object we need to pass is like

wb.SaveAs(filename, 51, System.Reflection.Missing.Value,
System.Reflection.Missing.Value, false, false, 1,1, true, 
System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value)

Here, 51 is is enumeration value for XLSX

For SaveAs in different file formats you can refer the xlFileFormat [2]

[1] https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel._workbook.saveas?view=excel-pia
[2] https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.xlfileformat?view=excel-pia

43
[+1] [2020-11-15 15:40:01] Klaus Oberdalhoff

I wonder why nobody suggested PowerShell with the free ImportExcel Module; it creates XML-Excel files (xlsx) with ease.

Especially easy when creating Excel-sheets coming from Databases like SQL Server...


FYI, the XLSX extension has nothing to do with XML. It is simply the modern (Office 2007+) version of the XLS file extension. - TylerH
(1) @TylerH They are XML based though. XLSX files are .zips of XML files, the same idea as the OpenOffice file formats. - Rup
@Rup Yes, the files are a proprietary wrapper around XML data. But that doesn't mean the files are "XML-Excel" files. They are just Excel files. - TylerH
44
[+1] [2021-09-28 17:33:59] toha

In my projects, I use some several .net libraries to extract Excel File (both .xls and .xlsx)

To Export data, I frequently use rdlc [1].

To modify excel files I use (Sample code when I try to set blank Cell A15):

ClosedXML [2]

        //Closed XML
        var workbook = new XLWorkbook(sUrlFile); // load the existing excel file
        var worksheet = workbook.Worksheets.Worksheet(1);
        worksheet.Cell("A15").SetValue("");
        workbook.Save();

IronXL [3]

       string sUrlFile = "G:\\ReportAmortizedDetail.xls";
        WorkBook workbook = WorkBook.Load(sUrlFile);
        WorkSheet sheet = workbook.WorkSheets.First();
        //Select cells easily in Excel notation and return the calculated value
        sheet["A15"].First().Value = "";
        sheet["A15"].First().FormatString = "";

        workbook.Save();
        workbook.Close();
        workbook = null;

SpireXLS [4] (When I try, the library print additional sheet to give information that we use the trial library

            string sUrlFile = "G:\\ReportAmortizedDetail.xls";
            Workbook workbook = new Workbook();
            workbook.LoadFromFile(sUrlFile);
            //Get the 1st sheet
            Worksheet sheet = workbook.Worksheets[0];
            //Specify the cell range
            CellRange range = sheet.Range["A15"];
            //Find all matched text in the range
            CellRange[] cells = range.FindAllString("hi", false, false);
            //Replace text
            foreach (CellRange cell in range)
            {
                cell.Text = "";
            }
            //Save
            workbook.Save();

Jet Oledb

    //ExcelTool Class
    public static int ExcelUpdateSheets(string path, string sWorksheetName, string sCellLocation, string sValue)
    {
        int iResult = -99;
        String sConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO'";
        OleDbConnection objConn = new OleDbConnection(sConnectionString);
        objConn.Open();
        OleDbCommand objCmdSelect = new OleDbCommand("UPDATE [" + sWorksheetName + "$" + sCellLocation + "] SET F1=" + UtilityClass.ValueSQL(sValue), objConn);
        objCmdSelect.ExecuteNonQuery();
        objConn.Close();

        return iResult;
    }

Usage :

    ExcelTool.ExcelUpdateSheets(sUrlFile, "ReportAmortizedDetail", "A15:A15", "");

Aspose

            var workbook = new Aspose.Cells.Workbook(sUrlFile);
            // access first (default) worksheet
            var sheet = workbook.Worksheets[0];
            // access CellsCollection of first worksheet
            var cells = sheet.Cells;
            // write HelloWorld to cells A1
            cells["A15"].Value = "";
            // save spreadsheet to disc
            workbook.Save(sUrlFile);
            workbook.Dispose();
            workbook = null;
[1] https://www.aspsnippets.com/Articles/Export-RDLC-Report-to-Excel-programmatically-in-ASPNet.aspx
[2] https://www.nuget.org/packages/ClosedXML/
[3] https://www.nuget.org/packages/IronXL.Excel
[4] https://www.e-iceblue.com/Tutorials/Spire.XLS/Getting-started/Spire.XLS-Quick-Start.html

45
[0] [2023-10-26 10:29:53] Dariusz Woźniak

Reposting answer from I want to create xlsx (Excel) file from c# [1]:


You may use the NPOI [2] library to create an Excel document. It doesn't require Office installed and doesn't use Interop / COM+. It also supports .NET Core.

using var workbook = new XSSFWorkbook();

var sheet = workbook.CreateSheet("Sheet1");

int rowIndex = 0;

var row = sheet.CreateRow(rowIndex++);
int cellIndex = 0;
row.CreateCell(cellIndex++).SetCellValue("ID");
row.CreateCell(cellIndex++).SetCellValue("Name");

var row = sheet.CreateRow(rowIndex++);
cellIndex = 0;
row.CreateCell(cellIndex++).SetCellValue("1");
row.CreateCell(cellIndex++).SetCellValue("One");

var row = sheet.CreateRow(rowIndex++);
cellIndex = 0;
row.CreateCell(cellIndex++).SetCellValue("2");
row.CreateCell(cellIndex++).SetCellValue("Two");


string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
string xlsxPath = Path.Combine(path, $"vdfgdfg.xlsx");

using var fileStream = new FileStream(xlsxPath, FileMode.Create, FileAccess.Write);
workbook.Write(fileStream);

Links:

[1] https://stackoverflow.com/questions/41605649/i-want-to-create-xlsx-excel-file-from-c-sharp/77366068#77366068
[2] https://github.com/nissl-lab/npoi

46
[-2] [2019-01-04 05:17:40] Shubham

check this out no need for third party libraries you can simply export datatable data to excel file using this

var dt = "your code for getting data into datatable";
            Response.ClearContent();
            Response.AddHeader("content-disposition", string.Format("attachment;filename={0}.xls", DateTime.Now.ToString("yyyy-MM-dd")));
            Response.ContentType = "application/vnd.ms-excel";
            string tab = "";
            foreach (DataColumn dataColumn in dt.Columns)
            {
                Response.Write(tab + dataColumn.ColumnName);
                tab = "\t";
            }
            Response.Write("\n");
            int i;
            foreach (DataRow dataRow in dt.Rows)
            {
                tab = "";
                for (i = 0; i < dt.Columns.Count; i++)
                {
                    Response.Write(tab + dataRow[i].ToString());
                    tab = "\t";
                }
                Response.Write("\n");
            }
            Response.End();

(4) That generates a tab-separated file and saves it with an .XLS extension so that it gets opened by Excel. It's not a real Excel file, and you can't include formatting etc. There are similar answers here which try the same trick with HTML and the wrong extension. - Rup
47
[-5] [2014-12-20 06:37:43] saurabh27

I am using following code for create excel 2007 file which create the file and write in that file but when i open the file but it give me error that exel cannot open the file bcz file might be coruupted or extension of the file is not compatible. but if i used .xls for file it work fines

for (int i = 0; i < TotalFile; i++)
{
    Contact.Clear();
    if (innerloop == SplitSize)
    {
        for (int j = 0; j < SplitSize; j++)
        {
            string strContact = DSt.Tables[0].Rows[i * SplitSize + j][0].ToString();
            Contact.Add(strContact);
        }
        string strExcel = strFileName + "_" + i.ToString() + ".xlsx";
                         File.WriteAllLines(strExcel, Contact.ToArray());
    }
}

also refer link

http://dotnet-magic.blogspot.in/2011/10/createformat-excel-file-from-cnet.html


(2) That all relies on your Contact class, and you haven't told us what that is. If it works for xls then chances are you're actually writing out HTML which isn't a real Excel file. And your link is using interop, which as mentioned above shouldn't be used server-side and can be slow filling large tables. - Rup
(1) Contact is linkedlist not a class.declare a linkledist and used it because i haven't know the size of data so i used linkedlist. - saurabh27
(1) Oh, so you're producing a plain text file with one item per line? So Excel is treating it as a CSV without the commas? - Rup
48