Как создать файл Excel (.XLS и .XLSX) на C# без установки Microsoft Office?

Как я могу создать электронную таблицу Excel с помощью C#, не требуя установки Excel на машине, на которой выполняется код?

@Mike Фрагмент "без установки Excel" не имеет ничего общего с профессионализмом. Это о зависимостях. Исходный текст вопроса был сформулирован так: «В идеале мне нужен открытый исходный код, поэтому мне не нужно добавлять какие-либо сторонние зависимости в свой код, и я бы не хотел напрямую использовать Excel для создания файла (с помощью OLE Automation)». К сожалению, вопрос был значительно упрощен.

Tony 02.04.2019 18:02

Предполагая, что вы пытались сделать что-то без библиотеки или внешнего кода, я не могу говорить о файле xls, но для файлов xlsx почему бы не начать с того, чтобы взять существующий, переименовать его в zip-файл и изучить его содержимое? Немногое реверс-инжиниринга многое вам расскажет. В разных папках и подпапках есть несколько разных XML-файлов и файлов rels. Попробуйте изучить это и посмотреть, можно ли это воспроизвести, или посмотрите, сможете ли вы найти документацию по различным пространствам имен / схемам xml.

Alexander Ryan Baggett 14.08.2019 00:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1 977
2
1 164 610
46
Перейти к ответу Данный вопрос помечен как решенный

Ответы 46

На самом деле вы можете захотеть проверить классы взаимодействия, доступные в C# (например, Microsoft.Office.Interop.Excel. Вы говорите, что нет OLE (а это не так), но классы взаимодействия очень просты в использовании. Ознакомьтесь с Документация по C# здесь (Interop for Excel начинается на странице 1072 документа C# PDF).

Вы можете быть впечатлены, если не пробовали их.

Обратите внимание на Microsoft позиция по этому поводу:

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.

Но вы должны убедиться, что вы все утилизируете вручную, иначе у вас будет утечка памяти.

MagicKat 30.09.2008 02:40

@Ricky B: Кроме того, по моему опыту взаимодействия, он действительно использует excel. Каждый раз, когда мы его использовали, если Excel не был установлен на машине, мы получали исключения COM.

MagicKat 30.09.2008 02:42

В случае OLE, даже при очень тщательной утилизации, в конечном итоге происходит утечка памяти или сбои. Это, пожалуй, нормально для обслуживаемых приложений / рабочих станций, но не рекомендуется для серверов (у MS есть база знаний, в которой это указано). Для нашего сервера мы просто перезагружаем его каждую ночь. Опять же, все работает нормально.

Jennifer Zouak 10.03.2010 00:54

@Geoffrey: ах, хорошо, ты собираешься заставить меня работать над этим :) -> support.microsoft.com/kb/257757 Microsoft в настоящее время не рекомендует и не поддерживает автоматизацию приложений Microsoft Office из любых автоматических, неинтерактивных клиентских приложений ...

Jennifer Zouak 11.03.2010 20:49

Я перехожу к этому обсуждению после того, как больше недели боролся с взаимодействием, и, если ваши потребности не очень просты, это не сработает. Поддержка форматирования вашей электронной таблицы ужасна, что, возможно, является причиной создания файла .xls, а не просто плоского файла .csv. Например, пробовали ли вы вывести в ячейке более 911 символов или пытались установить одинаковую ширину объединенных ячеек? У меня есть, и я не могу сказать вам, насколько я ненавижу это дерьмо сейчас ... Сделайте себе одолжение и воспользуйтесь одной из бесплатных библиотек, упомянутых в этом обсуждении.

md1337 03.02.2011 21:52

Я еще не изменил Interop на EPPlus (но уже на полпути), поэтому я действительно не знаю, насколько лучше с ним жизнь, но, имея дело с Interop, я испытывал столько боли в очень неожиданных случаях почти каждый раз, когда мне было нужно что-то более сложное, чем просто создать файл .xls / .xlsx с простой таблицей внутри. И упомянутая выше «магия дважды проверьте, чтобы избавиться от всего» - одна из тех повседневных проблем. Но да, это работает, и в большинстве случаев этого достаточно.

pkuderov 13.05.2013 19:11

Предупреждение: библиотека Microsoft.Office.Interops зависит от устанавливаемого Excel. Таким образом не отвечает на вопрос пользователя

Mark 03.12.2019 10:13

Он буквально говорит, что не хочет устанавливать офис.

JSON 21.10.2020 21:58

Чрезвычайно легким вариантом может быть использование HTML-таблиц. Просто создайте теги head, body и table в файле и сохраните его как файл с расширением .xls. Есть специальные атрибуты Microsoft, которые можно использовать для стилизации вывода, включая формулы.

Я понимаю, что вы, возможно, не кодируете это в веб-приложении, но вот пример композиции файла Excel через таблицу HTML. Этот метод можно использовать, если вы кодируете консольное приложение, настольное приложение или службу.

Это настолько специальное решение, но оно работает (не говоря уже о выдаче предупреждения об открытии в Excel) и настолько простое, что заслуживает своего решения. Хотя только для того, чтобы показать, что вы можете экспортировать файл excel :))

Luka Ramishvili 04.01.2012 11:23

Это решение сработало для меня, просто обратите внимание, что вы не можете использовать расширение .xlsx

Jill 30.03.2016 21:24

Некоторые люди в моей организации не могут открывать файлы Excel, созданные таким образом в Office 2010 и более поздних версиях. Не знаю, в чем проблема, но мне пришлось свернуть собственную реализацию OpenXML. (см. ответ Соггера)

Kristen Hammack 09.12.2016 01:55

ИКВМ + POI

Или вы можете использовать Interop ...

Вы можете использовать OLEDB для создания файлов Excel и управления ими. Проверьте это: Чтение и запись Excel с помощью OLEDB.

Типичный пример:

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();
}

РЕДАКТИРОВАТЬ - Еще несколько ссылок:

Может кто-нибудь подтвердить, работает ли это при работе в x64? Я почти уверен, что Jet работает только в том случае, если ваше приложение скомпилировано или запущено в 32-битном режиме.

Lamar 30.09.2008 05:45

Я только что проверил это соединение, и оно не удалось на Windows Server 2008 R2 x64 RC, кажется, что нужно установить драйвер системы Office 2007: Компоненты подключения к данным [microsoft.com/downloads/…

Chris Richner 16.06.2009 11:31

Будьте очень осторожны с этим - это большая уродливая путаница (например, иногда он угадывает тип столбца и отбрасывает все данные, которые не подходят).

dbkk 29.09.2009 13:02

При использовании этого метода нужно быть очень осторожным. Я обнаружил, что это очень ненадежно для данных, которые не в идеальном формате.

Kenny Mann 09.06.2010 20:03

Как человек, которому приходилось использовать OleDb в большом проекте, я говорю: «Держитесь подальше от него!» Иногда он не может получить значение ячейки только потому, что не может понять формат. У него нет операции удаления. Он работает совершенно иначе и непредсказуемо даже при малейшей смене провайдера. Я бы сказал, выбери проверенное коммерческое решение.

platypus 13.09.2014 22:32

Microsoft обновила Jet, попробуйте эту ссылку stackoverflow.com/questions/14401729/…

Justin 06.05.2016 00:36

В предыдущей работе мы использовали Распространяемый компонент ядра СУБД Microsoft Access 2010. Он принял форму драйвера OLEDB, который позволял читать и записывать файлы Excel, а также файлы формата Access. Обратите внимание, что эта загрузка не требует установки всего пакета Office. Также обратите внимание, что он поставляется как в 32-битном, так и в 64-битном вариантах. Очень важно сопоставить 32-битную или 64-битную версию с архитектура хост-процесса, который будет обращаться к файлу (ам). В нашем случае хост-процессом был SSIS.

Stephen G Tuggy 09.07.2016 08:33

Вы можете взглянуть на GemBox.Spreadsheet.

У них есть бесплатная версия со всеми функциями, но с ограничением до 150 строк на лист и 5 листов на книгу, если это соответствует вашим потребностям.

Сам пока не пользовался, но смотрится интересно.

Решение с открытым исходным кодом Java - POI Apache. Возможно, здесь есть способ настроить взаимодействие, но я недостаточно знаю Java, чтобы ответить на этот вопрос.

Когда я исследовал эту проблему, я остановился на сборках Interop.

Вы можете рассмотреть возможность создания файлов в формате Таблица XML 2003. Это простой формат XML с использованием хорошо документированная схема.

Вот способ сделать это с помощью LINQ to XML вместе с образцом кода:

Быстрый импорт и экспорт данных Excel с помощью LINQ to XML

Это немного сложно, поскольку вам нужно импортировать пространства имен и так далее, но это позволяет избежать любых внешних зависимостей.

(Кроме того, конечно, это VB .NET, а не C#, но вы всегда можете изолировать материал VB .NET в своем собственном проекте, чтобы использовать XML-литералы, а все остальное делать на C#.)

Я согласен с созданием таблиц XML, вот пример того, как это сделать для C# 3 (все просто пишут об этом в блогах в VB 9: P) http://www.aaron-powell.com/linq-to-xml-to-excel

Вы когда-нибудь пробовали силк?

Раньше мы генерировали таблицы Excel в классическом формате asp как sylk, а сейчас мы ищем также и Excelgenerater.

Преимущества sylk в том, что вы можете форматировать ячейки.

Различные доступные XML-библиотеки Office 2003 довольно хорошо работают с небольшими файлами Excel. Однако я считаю проблемой сам размер большой книги, сохраненной в формате XML. Например, рабочая книга, с которой я работаю, будет иметь размер 40 МБ в новом (и, по общему признанию, более плотно упакованном) формате XLSX, превратится в файл XML размером 360 МБ.

Насколько я понял, есть два коммерческих пакета, которые позволяют вывод в старые двоичные форматы файлов. Они есть:

Ни то, ни другое не из дешевых (я думаю, 500 и 800 долларов соответственно). но оба работают независимо от самого Excel.

Что мне было бы интересно, так это модуль вывода Excel для подобных OpenOffice.org. Интересно, можно ли их портировать с Java на .Net.

Этот работает как с .net, так и с java, и стоит недорого. SmartXLS smartxls.com

liya 03.12.2009 11:08

Коммерческое решение SpreadsheetGear для .NET сделает это.

Вы можете увидеть живые образцы ASP.NET (C# и VB) здесь и загрузить ознакомительную версию здесь.

Отказ от ответственности: я владею SpreadsheetGear LLC

У вас отличный продукт, но я думаю, что многие здесь ждут бесплатных решений. Это могло бы объяснить низкие голоса.

md1337 03.02.2011 21:43

Вы можете использовать ExcelXmlWriter.

Работает нормально.

Я недавно использовал FlexCel.NET и обнаружил, что это отличная библиотека! Я не говорю этого о слишком многих программных продуктах. Нет смысла описывать здесь всю коммерческую идею, вы можете прочитать обо всех функциях на их веб-сайте.

Это коммерческий продукт, но вы получите полный исходный код, если купите его. Итак, я полагаю, вы могли бы скомпилировать его в свою сборку, если бы действительно захотели. В противном случае это всего лишь одна дополнительная сборка для xcopy - без настройки, установки или чего-то в этом роде.

Я не думаю, что вы найдете способ сделать это без сторонних библиотек, поскольку .NET framework, очевидно, не имеет встроенной поддержки для этого, а OLE Automation - это просто целый мир боли.

Я использовал несколько вариантов:

Если XLSX необходим: ExcelPackage - хорошее начало, но оно исчезло, когда разработчик прекратил работу над ним. ExML взял оттуда и добавил несколько функций. ExML - неплохой вариант, я все еще использую его на нескольких производственных сайтах.

Однако для всех моих новых проектов я использую NPOI, порт .NET для POI Apache. НПОИ 2.0 (Альфа) также поддерживает XLSX.

Будьте осторожны с ExcelPackage, если вам нужно поддерживать XLS. Мне было трудно с этим, и в конце концов я перешел на ExcelLibrary.

Jeremy 17.09.2010 17:55

Определенно верно. ExcelPackage / ExML - хороший вариант, только если вам нужна поддержка XLSX.

Nate 21.09.2010 19:16

Обратите внимание, что у ExcelPackage есть преемник: EPPlus (epplus.codeplex.com), который поддерживает XLSX. Единственное, что меня беспокоит, по сравнению, например, с NPOI, - это производительность, например когда много столбцов.

Pragmateek 03.11.2013 23:00

Я успешно использовал следующие проекты с открытым исходным кодом:

  • ExcelPackage для форматов OOXML (Office 2007)

  • NPOI для формата .XLS (Office 2003). НПОИ 2.0 (Beta) также поддерживает XLSX.

Взгляните на мои сообщения в блоге:

Создание электронных таблиц Excel .XLS и .XLSX на C#

NPOI с таблицей Excel и динамической диаграммой

Примечание о NPOI - ссылки на строки и столбцы начинаются с нуля. Хорошо работает для заполнения существующего шаблона.

John M 30.04.2010 17:45

Я тоже голосую за GemBox.Spreadsheet.

Очень быстрый и простой в использовании, с множеством примеров на их сайте.

Взял свои задачи по отчетности на совершенно новый уровень скорости выполнения.

Бесплатная версия ограничена: максимальное количество строк на листе - 150.

Kiquenet 11.12.2020 18:43

Некоторая полезная автоматизация Excel на C#, вы можете найти по следующей ссылке.

http://csharp.net-informations.com/excel/csharp-excel-tutorial.htm

Болтон.

Что ж,

вы также можете использовать стороннюю библиотеку, например Задавать.

Эта библиотека имеет то преимущество, что не требует установки Excel на вашем компьютере, что было бы идеально в вашем случае.

Чтобы быть более точным, вы можете использовать Aspose.Cells для .NET, чтобы создавать файлы Excel (XLS, XLSX) в вашем приложении .NET.

Shahzad Latif 29.08.2011 15:55

Да, вы можете, если вы не против заплатить минимальный лицензионный сбор в размере 999 долларов. Попробуйте библиотеку MikesKnowledgeBase ... которая на 999 долларов дешевле этой !!

Mike Gledhill 05.01.2012 17:10

Если вам нравится формат xlsx, попробуйте мой проект GitHub, EPPlus. Все началось с исходников из ExcelPackage, но сегодня это полная переработка. Он поддерживает диапазоны, стили ячеек, диаграммы, формы, изображения, именованные диапазоны, автофильтр и многое другое.

Лицензия теперь LGPL, примечания к выпуску здесь: epplus.codeplex.com/releases/view/79802

Simon D 05.02.2012 16:30

Примеры были полезны. Мне удалось сменить код с использованием библиотеки взаимодействия Microsoft (ужасно медленной) на эту библиотеку (версия 4.x) за пару часов. Мой тест записывает файл с двумя вкладками и примерно 750 000 ячеек. Использование взаимодействия с MS заняло 13 минут. Использование EPPlus заняло 10 секунд, что примерно в 80 раз больше. Очень счастлив!

Paul Chernoch 10.02.2015 21:55

@ JanKällman Вам следует обновить страницу CodePlex, чтобы показать, что у вас есть доступные методы: LoadFromCollection<T>, LoadFromDataTable и т. д. (Можно найти через здесь)

PeterX 24.02.2015 06:39

Для ясности в этом треде, LGPL позволяет связывать программное обеспечение без возникновения заразной части GPL. Вам нужно только открыть исходный код изменений, которые вы вносите в ClosedXml, или если вы напрямую помещаете исходный код (в отличие от ссылок на сборки ClosedXml) внутри своего приложения, тогда вам нужно открыть исходный код вашего приложения.

Chris Marisic 12.08.2015 19:10

@Paul Chernoch: Мы очень быстро заполняем большие листы Excel с помощью взаимодействия. Секрет в том, чтобы сделать массовое обновление. Создайте блок объекта [,], заполните его, затем запишите эту матрицу в Excel за один раз: excelWorksheet.get_Range (range) .Value2 = block;

Marc Meketon 16.02.2018 01:53

Похоже, лицензирование переходит с LGPL на лицензию Polyform Noncommercial 1.0.0.

Luke 21.02.2020 09:48

EPPlus версии 5 не бесплатно?

Kiquenet 08.12.2020 20:37
Ответ принят как подходящий

Вы можете использовать библиотеку под названием ExcelLibrary. Это бесплатная библиотека с открытым исходным кодом, размещенная на Google Code:

ExcelLibrary

Похоже, это порт PHP ExcelWriter, о котором вы упомянули выше. Он пока не будет записывать в новый формат .xlsx, но они работают над добавлением этой функции в.

Это очень просто, компактно и удобно. Кроме того, у него есть DataSetHelper, который позволяет использовать DataSets и DataTables для простой работы с данными Excel.

ExcelLibrary, похоже, по-прежнему работает только со старым форматом Excel (файлы .xls), но, возможно, в будущем добавит поддержку для новых форматов 2007/2010.

Вы также можете использовать EPPlus, который работает только с файлами формата Excel 2007/2010 (файлы .xlsx). Также есть NPOI, который работает с обоими.

В каждой библиотеке есть несколько известных ошибок, как указано в комментариях. В целом, EPPlus кажется лучшим выбором с течением времени. Похоже, он более активно обновляется и документируется.

Кроме того, как отмечает @ АртёмЦарионов ниже, EPPlus поддерживает сводные таблицы, а ExcelLibrary может иметь некоторую поддержку (Проблема со сводной таблицей в ExcelLibrary)

Вот пара ссылок для быстрого ознакомления:
ExcelLibrary - GNU Lesser GPL
EPPlus - GNU (LGPL) - больше не поддерживается
EPPlus 5 - Polyform Noncommercial - С мая 2020 г.
NPOI - Лицензия Apache

Вот пример кода для ExcelLibrary:

Вот пример получения данных из базы данных и создания из нее книги. Обратите внимание, что код ExcelLibrary представляет собой единственную строку внизу:

//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);

Создать файл Excel так просто. Вы также можете вручную создавать файлы Excel, но меня действительно впечатлила вышеуказанная функциональность.

ExcelLibrary был заменен исключительным EPPlus - epplus.codeplex.com. Ян регулярно обновляет его. Мы использовали его, и это один из лучших проектов с открытым исходным кодом, с которыми мы работали.

Mark A 04.11.2010 03:11

Следует отметить, что ExcelLibrary имеет множество проблем с производительностью при работе с большими наборами данных (более 5000 строк с большим количеством столбцов). В настоящее время выполняется серьезная модификация базы кода на работе, чтобы мы могли использовать ее в проекте.

rossisdead 19.10.2011 03:17

EPPlus кажется гораздо менее глючным, чем ExcelLibrary, НО это GPL и, следовательно, только решение для проектов с открытым исходным кодом.

Seth 27.01.2012 03:21

-1 Если вы собираетесь опубликовать образец кода, вы также можете убедиться, что он правильный. Используйте метод Dispose этого интерфейса, чтобы явно освободить неуправляемые ресурсы вместе со сборщиком мусора. Потребитель объекта может вызвать этот метод, когда объект больше не нужен.

ta.speot.is 22.02.2014 13:44

EPPlus фактически по-прежнему технически GPL, потому что это производная работа (т. Е. Кодовая база по-прежнему основана на ExcelLibrary, и, поскольку это GPL, то же самое и EPPlus ... вы не можете внести некоторые изменения в код GPL и использовать лицензию LGPL. в теме). Кто-нибудь знает, как писать в Excel, используя коммерческий код или истинный LGPL (или аналогичный лицензионный код).

Beep beep 27.01.2015 23:48

ExcelLibrary больше не работает. Если вы хотите писать файлы Excel 2003 (.xls), эта библиотека отлично работает: CSharpJExcel sourceforge.net/projects/jexcelapi Убедитесь, что вы загрузили порт C#.

Chris 28.10.2015 18:06

А что насчет ClosedXML? Я могу оказаться полезным в ваших проектах.

Amadeus Sánchez 30.11.2015 21:10

Может быть aspose.com/products/cells или gemboxsoftware.com/spreadsheet/overview

Kiquenet 15.07.2016 14:44

Я попробовал ExcelLibrary, все, что он мог сделать, это создать «поврежденный файл», ничего особенного, всего 3 столбца, небольшой файл. Excel 2016 не открывался. Пробовал автоматическое создание файлов ROM DataTable.

Vega4 28.04.2020 15:41

EPPlus - это LGPL до версии 5. Если вы используете в своем коде версию 5 или выше, будет создано исключение, если у вас нет лицензионного ключа.

Britt Kelly 18.06.2020 20:34

Вы можете просто записать его в XML, используя формат Excel XML, и назвать его с расширением .XLS, и он откроется в excel. Вы можете управлять всем форматированием (полужирным шрифтом, шириной и т. д.) В заголовке XML-файла.

Есть пример XML из Википедии.

Если вы создаете файлы Excel 2007/2010, попробуйте этот проект с открытым исходным кодом: 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");

Я пробовал использовать это в проекте, который строит довольно большие листы Excel. Отличная библиотека, но очень плохая по производительности. Я только что сравнил проект, над которым я работаю: ClosedXML (v 0.53.3) занял 92 489 мс, тогда как EPPlus (v 2.9.03, для тестирования - мы не можем использовать, потому что это GPL) занял 16 500 мс.

Druid 08.06.2011 16:40

@Druid лицензия LGPL при условии, что вы не изменяете исходный код на ClosedXML, можно бесплатно использовать epplus.codeplex.com/license

Chris Marisic 12.08.2015 19:08

Вы можете создавать красиво отформатированные файлы Excel с помощью этой библиотеки: http://officehelper.codeplex.com/documentation
См. Образец ниже:

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");
}        

где образец выглядит так:

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};
    }
}

Устаревший код в codeplex?

Kiquenet 11.12.2020 18:41

http://www.codeproject.com/KB/cs/Excel_and_C_.aspx <= почему бы просто не использовать встроенный Power Windows, просто установить офис на сервере, любое приложение, которое вы устанавливаете, можно автоматизировать.

Намного проще просто использовать собственные методы.

Если он установлен, вы можете использовать его, это самая крутая и малоиспользуемая функция в Windows, она была названа COM еще в старые добрые времена, и это экономит вам массу времени и боли.

Или, что еще проще, просто используйте расходные материалы ref lib MS - http://csharp.net-informations.com/excel/csharp-create-excel.htm

Почему второй способ проще? Разве это не то же самое (добавление библиотеки собственных объектов в ваш проект)? Вам нужно установить Excel, чтобы эта библиотека объектов работала?

Slauma 09.02.2011 15:45

Microsoft не рекомендует и не поддерживает автоматизацию Office из неинтерактивных приложений, таких как ASP.NET. См. support.microsoft.com/kb/257757

TrueWill 09.02.2011 21:17

Когда дело доходит до автоматизации, Excel работает ненадежно и медленно.

Leslie Godwin 25.06.2015 12:21

Некоторые сторонние поставщики компонентов, такие как Infragistics или Syncfusion, предоставляют очень хорошие возможности экспорта в Excel, которые не требуют установки Microsoft Excel.

Поскольку эти поставщики также предоставляют расширенные компоненты сетки пользовательского интерфейса, эти компоненты особенно удобны, если вы хотите, чтобы стиль и макет экспорта в Excel имитировали текущее состояние сетки в пользовательском интерфейсе вашего приложения.

Если ваш экспорт предназначен для выполнения на стороне сервера с акцентом на экспортируемые данные и без ссылки на пользовательский интерфейс, я бы выбрал один из бесплатных вариантов с открытым исходным кодом (например, ExcelLibrary).

Раньше я участвовал в проектах, в которых пытались использовать автоматизацию на стороне сервера в пакете Microsoft Office. Основываясь на этом опыте, я настоятельно рекомендую не использовать такой подход.

Посмотрите примеры создания файлов Excel.

Примеры есть в C# и VB.NET

Он управляет файлами XLS XLSX и CSV Excel.

http://www.devtriogroup.com/ExcelJetcell/Samples

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);
            }
        }
    }
}

Привет, это решение - экспортировать представление сетки в файл Excel, это может вам помочь

Нет, это генерирует HTML, помеченный как файл Excel, а не как настоящий файл Excel. Да, сам Excel откроет это нормально, но другие программы, использующие электронные таблицы, в том числе, например, бесплатное средство просмотра Excel от Microsoft, не примут его. Лучше создать настоящий файл Excel, используя одну из библиотек здесь.

Rup 28.04.2011 15:46

Вы также должны использовать System.Net.Mime.ContentDisposition для генерации текста заголовка Content-Disposition, а не добавления строки - это правильно справится с именами файлов, которые содержат пробелы и т. д.

Rup 28.04.2011 15:48

GridViewExportUtil только для Интернета. А для Windows Forms, WPF, консоли, служебной Windows, модульного теста или надстройки?

Kiquenet 11.12.2020 18:42

А как насчет использования Open XML SDK 2.0 для Microsoft Office?

Несколько преимуществ:

  • Не требует установки Office
  • Сделано Microsoft = достойная документация MSDN
  • Всего одна .Net dll для использования в проекте
  • SDK поставляется с множеством инструментов, таких как diff, validator и т. д.

Ссылки:

Важно отметить, что размер DLL для этого составляет чуть более 5 МБ и ограничен форматами Office 2007. Но, безусловно, самое простое и быстрое решение, которое мне подходит.

Josh Brown 20.09.2011 17:03

Просто предупреждаю, что v2.5 отсутствует и может быть загружена здесь.

Snuffleupagus 04.01.2013 20:47

SDK моделирует XML в классы, так что каждый тег XML сопоставляется с тегом, а затем вам необходимо правильно построить иерархию классов (каждый экземпляр имеет набор дочерних экземпляров / тегов). Это означает, что вы должны знать XML-структуру файла Excel, что очень сложно. Намного проще использовать упомянутую выше оболочку, такую ​​как EPPlus, которая упрощает работу.

Tsahi Asher 24.12.2014 19:27

Отличный образец Microsoft Open XML SDK - Open XML Writer можно найти по адресу polymathprogrammer.com/2012/08/06/… Или см. Решение для переполнения стека stackoverflow.com/questions/11370672/…

Greg 17.02.2017 20:51

Я считаю, что средство записи Open XML из пакета Microsoft Open XML SDK великолепно. Используя приведенные выше решения (особенно образец Винсента Тома (Poly Math)), легко создать писатель, который обрабатывает большие наборы данных и записывает записи способом, аналогичным и не слишком сложным для того, что вы бы сделали для CSV; но вместо этого вы пишете xml. Open XML - это образ мышления, в котором Microsoft считает свои новые форматы Office. И вы всегда можете переименовать их из .xslx в .zip-файлы, если вам захочется потрогать их XML-содержимое.

Greg 17.02.2017 20:54

Обратите внимание, что Open XML SDK теперь имеет открытый исходный код и размещен на github. Также вам не нужно устанавливать SDK, просто запустите nuget и DocumentFormat.OpenXml - это все, что вам нужно. Он работает со стандартом .net 1.3.

horeaper 31.05.2018 02:37

Как это было интересно, и ваш ответ заставил меня это усвоить. Я только начал заниматься программированием и мне интересен такой контент.

elnaz jangi 12.06.2020 16:33

Не забудьте загрузить Инструмент повышения производительности OpenXML с сайта Microsoft при использовании этого API. Как я работаю: создайте документ с нужным мне содержанием и форматом в Excel и сохраните его. Откройте его с помощью инструмента. Очистите интересующий меня код от кода, отраженного в инструменте, и начните с него. Я также использую этот инструмент для проверки и проверки своих результатов на ошибки. Когда я хочу добавить новую функцию в свой код, я использую функцию инструментов «Diff», чтобы выяснить, как эта функция должна быть закодирована. Это действительно важный инструмент разработки OpenXML

Flydog57 02.12.2020 20:12

Просто хочу добавить еще одну ссылку на стороннее решение, которое напрямую решает вашу проблему: http://www.officewriter.com

(Отказ от ответственности: я работаю в SoftArtisans, компании, которая делает OfficeWriter)

Вот полностью бесплатная библиотека C#, которая позволяет экспортировать из DataSet, DataTable или List<> в настоящий файл Excel 2007 .xlsx, используя библиотеки OpenXML:

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

Предоставляется полный исходный код - бесплатно - вместе с инструкциями и демонстрационным приложением.

После добавления этого класса в приложение вы можете экспортировать DataSet в Excel всего одной строкой кода:

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

Нет ничего проще ...

И для этого даже не требуется наличие Excel на вашем сервере.

Это кажется немного вводящим в заблуждение, поскольку вы просите пожертвование, чтобы получить все функции.

UrbanEsc 23.01.2017 18:33

Отчасти это правда: полностью бесплатная версия создаст для вас идеальный файл .xlsx, и весь исходный код предоставлен. Если вы пожертвуете 10 долларов или более одной из этих двух благотворительных организаций (от которых я не получаю абсолютно ничего), то вы получите «лучшую» версию, показывающую, как выполнять форматирование, даты и т. д. Учитывая стоимость сторонних продуктов, я полагаю Вместо этого пожертвование 10 долларов на доброе дело того стоит!

Mike Gledhill 02.05.2017 17:15

Я использую следующий код для создания файла excel 2007, который создает файл и записывает в этот файл, но когда я открываю файл, он дает мне ошибку, которая exel не может открыть файл. Возможно, файл bcz поврежден или расширение файла несовместимо. но если я использовал .xls для файла, он работал штраф

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());
    }
}

также ссылка

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

Все это зависит от вашего класса Contact, и вы не сказали нам, что это такое. Если это работает для xls, скорее всего, вы на самом деле пишете HTML, который не является настоящим файлом Excel. И ваша ссылка использует взаимодействие, которое как указано выше не должно использоваться на стороне сервера и может медленно заполнять большие таблицы.

Rup 22.12.2014 23:48

Контакт - это связанный список, а не класс. Объявить связанный список и использовать его, потому что я не знаю размера данных, поэтому я использовал связанный список.

saurabh27 23.12.2014 12:53

О, так вы создаете простой текстовый файл с одним элементом в строке? Значит, Excel рассматривает его как CSV без запятых?

Rup 23.12.2014 12:55

Я написал простой код для экспорта набора данных в Excel без использования объекта excel с помощью System.IO.StreamWriter.

Ниже приведен код, который будет читать все таблицы из набора данных и записывать их на листы одну за другой. Я воспользовался помощью эта статья.

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();
    }

Однако, как говорится в статье, это XML, который Excel будет читать, а не на самом деле файл XLS, что означает, что он может работать только в Excel, а не в других программах, которые читают электронные таблицы. Но это, вероятно, лучше, чем ответы в эквивалентной таблице HTML здесь!

Rup 23.07.2015 12:39

Поддерживает xlsx? OpenXML?

Kiquenet 08.12.2020 20:54

Типа это Open XML, но вы можете писать только файл .xls и отлично работает. Позаботьтесь о пустых местах в тегах. Используйте мой код, отредактированный ниже.

Mauricio Kenny 08.12.2020 23:22

OpenXML также является хорошей альтернативой, которая помогает избежать установки MS Excel на сервере. Open XML SDK 2.0, предоставляемый Microsoft, упрощает задачу управления пакетами Open XML и базовыми элементами схемы Open XML внутри пакета. Интерфейс прикладного программирования (API) Open XML инкапсулирует множество общих задач, которые разработчики выполняют с пакетами Open XML.

Проверьте это OpenXML: альтернатива, которая помогает избежать установки MS Excel на сервере

Syncfusion Essential XlsIO может это сделать. Он не зависит от Microsoft Office, а также имеет специальную поддержку для разных платформ.

Пример кода:

//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);

Полный набор средств управления доступен бесплатно через программу общественная лицензия, если вы соответствуете требованиям (доход менее 1 миллиона долларов США). Примечание: я работаю в Syncfusion.

Syncfusion Не бесплатно

Kiquenet 08.12.2020 20:51

Самый простой и быстрый способ создать файл Excel из C# - использовать инструмент повышения производительности Open XML. Инструмент повышения производительности Open XML поставляется с установкой Open XML SDK. Инструмент выполняет обратное преобразование любого файла Excel в код C#. Затем код C# можно использовать для повторного создания этого файла.

Обзор вовлеченного процесса:

  1. Установите Open XML SDK с помощью инструмента.
  2. Создайте файл Excel с помощью последней версии клиента Excel с желаемым видом. Назовите его DesiredLook.xlsx.
  3. С помощью инструмента откройте DesiredLook.xlsx и нажмите кнопку Reflect Code вверху.
  4. Код C# для вашего файла будет создан на правой панели инструмента. Добавьте это в свое решение C# и сгенерируйте файлы с желаемым видом.

В качестве бонуса этот метод работает с любыми файлами Word и PowerPoint. Как разработчик C#, вы затем внесете в код изменения в соответствии со своими потребностями.

Я разработал простое приложение WPF на github, который будет работать в Windows для этой цели. Существует класс-заполнитель GeneratedClass, куда вы можете вставить сгенерированный код. Если вы вернетесь к одной версии файла, он сгенерирует файл Excel, подобный этому:

Я еще не пробовал это решение Open XML SDK, но вау, я обязательно его проверю. Я работал с подобными инструментами много лет и не знал об этом. Я опубликовал свой собственный простой FOSS для преобразования файлов в XLSX с помощью .NET: github.com/TonyGravagno/NebulaXConvert

TonyG 26.07.2018 19:34

Если вы создаете таблицу данных или datagridview из кода, вы можете сохранить все данные, используя этот простой метод. Этот метод не рекомендуется, но он работает на 100%, даже если вы не устанавливаете MS Excel на свой компьютер.

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!");
   }

Некоторое время назад я создал DLL поверх NPOI. Пользоваться им очень просто:

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

Вы можете прочитать об этом на здесь.

Кстати, это 100% открытый исходный код. Не стесняйтесь использовать, редактировать и делиться;)

Один действительно простой вариант, о котором часто забывают, - это создать отчет .rdlc с использованием Отчетность Microsoft и экспортировать его в формат Excel. Вы можете создать его в Visual Studio и сгенерировать файл, используя:

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

Вы также можете экспортировать его в .doc или .pdf, используя "WORDOPENXML" и "PDF" соответственно, и он поддерживается на многих различных платформах, таких как ASP.NET и SSRS.

Намного проще вносить изменения в визуальный дизайнер, где вы можете видеть результаты, и поверьте мне, как только вы начнете группировать данные, форматировать заголовки групп, добавлять новые разделы, вы не захотите возиться с десятками узлов XML.

полный образец исходного кода? rdlc выдает память в ASP.NET travis.io/blog/2014/10/27/rdlc-performance-issues-dotnet45 и stackoverflow.com/questions/33436607/…

Kiquenet 11.12.2020 18:46

Чтобы сохранить xls в формате xlsx, нам просто нужно вызвать метод SaveAs из библиотеки Microsoft.Office.Interop.Excel. Этот метод принимает около 16 параметров, и один из них также является форматом файла.

Документ Microsoft: Здесь Аргументы метода SaveAs

Объект, который нам нужно передать, похож на

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)

Здесь 51 - это значение перечисления для XLSX.

Для SaveAs в различных форматах файлов вы можете обратиться к xlFileFormat

Также есть старый ответ об использовании Office Interop.

Rup 05.11.2018 17:45

проверьте это, нет необходимости в сторонних библиотеках, вы можете просто экспортировать данные с данными в файл Excel, используя это

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();

Это создает файл с разделением табуляцией и сохраняет его с расширением .XLS, чтобы его открывал Excel. Это не настоящий файл Excel, и вы не можете включать форматирование и т. д. Здесь есть похожие ответы, в которых используется тот же трюк с HTML и неправильным расширением.

Rup 04.01.2019 12:44

Как создать файл Excel (.xslx) с помощью C# в OneDrive без установки Microsoft Office

Microsoft Graph API предоставляет API файлов и Excel для создания и изменения файлов Excel, хранящихся в OneDrive, как для корпоративных, так и для пользовательских учетных записей. Пакет NuGet Microsoft.Graph предоставляет множество интерфейсов для работы с API файлов и Excel.

{
  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);
}

На этом этапе у вас есть файл Excel, созданный в OneDrive пользователя (предприятия или потребителя) или группы. Теперь вы можете использовать от API Excel до вносить изменения в файл Excel без использования Excel и без понимания формата Excel XML.

полный образец? что такое graphClient? ResourceHelper? ExcelTestResource - это пустой файл Excel шаблона?

Kiquenet 11.12.2020 18:48

@Kiquenet graphClient находится в пакете NuGet Microsoft.Graph. Да, ExcelTestResource - это пустой файл Excel. ResourceHelper получает пустой поток файла Excel. Вот пример, в котором используется GraphServiceClient (в этом примере graphClient): github.com/microsoftgraph/dotnetcore-console-sample. В нем нет примера использования API Excel.

Michael Mainer 12.12.2020 20:11

Вы можете попробовать мою библиотеку SwiftExcel. Эта библиотека записывает непосредственно в файл, поэтому она очень эффективна. Например, вы можете записать 100 тыс. Строк за несколько секунд без использования памяти.

Вот простой пример использования:

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);
        }
    }
}

Вы можете установить пакет OpenXml nuget в Visual Studio. Вот небольшой код для экспорта таблицы данных в файл Excel:

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 будет SpreadsheetDocument.Create?

Kiquenet 30.01.2021 11:30

Интересно, почему никто не предложил PowerShell с бесплатным модулем ImportExcel; он с легкостью создает файлы XML-Excel (xlsx).

Особенно просто при создании таблиц Excel из баз данных, таких как SQL Server ...

К вашему сведению, расширение XLSX не имеет ничего общего с XML. Это просто современная (Office 2007+) версия расширения файла XLS.

TylerH 16.11.2020 00:27

@TylerH Но они основаны на XML. Файлы XLSX представляют собой файлы .zip XML, аналогичные форматам файлов OpenOffice.

Rup 16.11.2020 12:27

@Rup Да, файлы представляют собой проприетарную оболочку XML-данных. Но это не значит, что файлы являются файлами «XML-Excel». Это просто файлы Excel.

TylerH 16.11.2020 23:12

Я снова перекодировал код, и теперь вы можете создать файл .xls, позже вы можете преобразовать его в формат Open XML Excel 2003.

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();
    }

Другие вопросы по теме