Як створити файл Excel (.XLS та .XLSX) у C #, не встановлюючи Microsoft Office?


1889

Як я можу створити таблицю Excel за допомогою C #, не вимагаючи встановлення Excel на машині, на якій працює код?


"... без встановлення Ms Office?" частина питання звучить дуже непрофесійно. Ви можете генерувати будь-який тип файлів із програми C # (з одним xlsабо xlsxодним із них). Це не вимога, щоб на вашому комп’ютері була програма, яка може її читати (скажімо, бінарну).
Майк

30
@Mike Частка "без встановлення Excel" не має нічого спільного з професійністю. Йдеться про залежності. Оригінальний текст питання був сформульований так: "В ідеалі я хотів би відкритий код, тому мені не потрібно додавати будь-які сторонні залежності до свого коду, і я хотів би уникати використання Excel безпосередньо для створення файлу (використовуючи OLE Автоматизація.) " Прикро питання було різко спрощене.
Тоні

5
Якщо припустити, що ви намагалися зробити щось із бібліотеки чи зовнішнього коду, я не можу говорити про файл xls, але для файлів xlsx, чому б не почати з того, щоб взяти наявний, перейменувати його на zip-файл та вивчити вміст? Трохи зворотна інженерія скаже вам зовсім небагато. У різних папках і вкладених папках є кілька різних xml-файлів і файлів rels. Спробуйте дослідити це і побачити, чи це щось, що ви можете повторити або побачити, чи зможете ви знайти документацію на різні простори / схеми імен xml.
Олександр Райан

@AlexanderRyanBaggett Це було надзвичайно корисно! Під час роботи над публікацією, яка працює над автоматичним створенням звітів та вивченням документів у вигляді zip-архіву, можна ознайомитись із питаннями створення файлу документів.
SentientFlesh

Відповіді:


1054

Можна використовувати бібліотеку під назвою ExcelLibrary. Це безкоштовна бібліотека з відкритим кодом, розміщена на Google Code:

ExcelLibrary

Схоже, це порт PHP ExcelWriter, про який ви згадали вище. Він ще не запише у новий формат .xlsx, але вони працюють над тим, щоб додати цю функціональність у.

Це дуже просто, мало і просто у використанні. Плюс у ньому є DataSetHelper, який дозволяє використовувати набори даних та таблиці даних для легкої роботи з даними Excel.

Здається, ExcelLibrary як і раніше працює лише для більш старого формату Excel (.xls файли), але може надавати підтримку в майбутньому для нових форматів 2007/2010.

Ви також можете використовувати EPPlus , який працює лише для файлів формату Excel 2007/2010 (файли .xlsx). Також є NPOI, який працює з обома.

У кожній бібліотеці є кілька відомих помилок, як зазначено в коментарях. Взагалі, EPPlus, здається, є найкращим вибором з часом. Здається, це також більше оновлюється та документується.

Також, як зазначає @ АртёмЦарионов нижче, EPPlus має підтримку зведених таблиць, а ExcelLibrary може мати деяку підтримку ( випуск зведеної таблиці в ExcelLibrary )

Ось кілька посилань для швидкого ознайомлення:
ExcelLibrary - GNU Менша GPL
EPPlus - GNU Менша загальна публічна ліцензія (LGPL)
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 вручну, але перерахована вище функціональність мене справді вразила.


247
ExcelLibrary була замінена винятковим EPPlus - epplus.codeplex.com . Ян регулярно її оновлює. Ми використовували його, і це один з найкращих проектів з відкритим кодом, з яким ми працювали.
Марк А

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

EPPlus здається набагато меншим баггі, ніж ExcelLibrary, але це GPL і тому лише рішення для проектів з відкритим кодом.
Сет


6
Що про ClosedXML ? Я можу виявитись корисним у ваших проектах.
Amadeus Sánchez

589

Якщо ви задоволені форматом xlsx, спробуйте мій проект GitHub, EPPlus . Він розпочався з джерела з ExcelPackage, але сьогодні це повне перезапис. Він підтримує діапазони, стилізацію комірок, діаграми, фігури, зображення, названі діапазони, автофільтр та багато іншого.


77
Ліцензія тепер LGPL, нотатки про випуск тут: epplus.codeplex.com/releases/view/79802
Simon D

13
Приклади були корисними. Я зміг змінити свій код з використання бібліотеки інтероп Microsoft (жахливо повільно) на цю бібліотеку (версія 4.x) за пару годин. Мій орієнтир записує файл з двома вкладками та приблизно 750 000 комірок. За допомогою інтеропа MS було потрібно 13 хвилин. Використання EPPlus зайняло 10 секунд, приблизно 80-кратне прискорення. Дуже щасливий!
Павло Чорноч

3
Для наочності в цій нитці LGPL дозволяє зв'язати програмне забезпечення без інфікованої частини GPL. Вам потрібно лише відкрити зміни, які ви вносите в ClosedXml, або якщо ви безпосередньо введете вихідний код (на відміну від посилань на збірки ClosedXml) всередині своєї програми, тоді вам потрібно відкрити вихідну програму.
Кріс Марісіч

4
@Paul Chernoch: Ми швидко заповнюємо великі листи Excel інтеропом. Секрет - робити масове оновлення. Створіть об'єкт [,] блок, заповніть його, а потім запишіть цю матрицю в Excel за один раз: excelWorksheet.get_Range (діапазон) .Value2 = блок;
Марк Мекетон

2
Схоже, ліцензування переходить від LGPL до ліцензії Polyform некомерційної 1.0.0
Лук

175

А як щодо використання Open XML SDK 2.0 для Microsoft Office?

Кілька переваг:

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

Посилання:


3
Важливо зауважити, що DLL для цього становить трохи більше 5 Мб і обмежений форматами Office 2007. Але, безумовно, найпростіше і найшвидше рішення, яке працює для мене.
Джош Браун

18
Лише вгору, що версія v2.5 вимкнена, і її можна завантажити тут .
Snuffleupagus

10
SDK моделює XML у класи, так що кожен тег XML відображається в тезі, і тоді ви повинні правильно скласти ієрархію класів (кожен екземпляр має колекцію дочірніх екземплярів / тегів). Це означає, що ви повинні знати XML-структуру файлу Excel, яка дуже складна. Набагато простіше використовувати обгортку, таку як EPPlus, згадану вище, що спрощує речі.
Цахі Ашер

2
Чудовий зразок Microsoft Open XML SDK - Open XML Writer можна знайти на сайті polymathprogrammer.com/2012/08/06/… Або дивіться рішення Stack Overflow stackoverflow.com/questions/11370672/…
Грег

4
Мені здалося, що Open XML Writer Microsoft Open XML SDK чудовий. Використовуючи наведені вище рішення (особливо зразок Вінцента Тома (Poly Math)), легко створити письменника, який передає великі набори даних і записує записи подібними та не надто складними тим, що ви робите для CSV; але ви замість цього пишете XML. Відкритий XML - це розум, який Microsoft вважає, що це нові формати Office. І ви завжди можете перейменовувати їх з .xslx в .zip файли, якщо вам здається, що тикаєте на їх вміст XML.
Грег

167

Я успішно використовував такі проекти з відкритим кодом:

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

  • NPOI для формату .XLS (Office 2003). NPOI 2.0 (Beta) також підтримує XLSX.

Погляньте на мої повідомлення в блозі:

Створення електронних таблиць Excel .XLS та .XLSX у C #

NPOI з таблицею Excel та динамічною діаграмою


6
Примітка про NPOI - Посилання на рядки та стовпці базуються на нулі. Чи добре працює для заповнення існуючого шаблону.
Джон М

108

Ви можете використовувати 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();
}

EDIT - Ще кілька посилань:


4
Чи може хтось підтвердити, чи працює це під час запуску в x64? Я впевнений, що Jet працює лише в тому випадку, якщо ваша програма складена або працює в 32-бітному режимі.
Ламар

2
Я щойно тестував це з'єднання, і він не вдався на Windows Server 2008 R2 x64 RC, схоже, треба встановити драйвер Office 2007: Компоненти підключення до даних [ microsoft.com/downloads/…
Кріс Річнер

25
Будьте дуже обережні з цим - це великий некрасивий затишок (наприклад, іноді він вгадує тип стовпця і відкидає всі дані, які не відповідають).
dbkk

9
Слід бути дуже обережним, якщо використовувати цей метод. Я вважаю, що це дуже нестабільні дані, які не в ідеальному форматі.
Кенні Манн

9
Як людина, якій довелося використовувати OleDb у великому проекті, я кажу, ЗАСТОСУЙТЕ З НЕГО! Іноді він не в змозі отримати значення комірки лише тому, що не міг зрозуміти формат. У ньому немає операції видалення. Він працює зовсім інше і непередбачувано навіть при найменшій зміні постачальника. Я б сказав, що потрібно перевірити комерційне рішення.
Caner Öncü

80

Комерційне рішення SpreadsheetGear для .NET це зробить.

Ви можете побачити зразки ASP.NET (C # і VB) тут, а завантажити оціночну версію тут .

Відмова: Я є власником SpreadsheetGear LLC


10
У вас чудовий продукт, але я думаю, що багато людей тут очікують безкоштовних рішень. Це може пояснити зниження голосів.
md1337

65

Я використав кілька варіантів:

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

Однак для всіх моїх нових проектів я використовую NPOI , .NET порт AI- POI Apache . NPOI 2.0 (Alpha) також підтримує XLSX.


Будьте обережні з ExcelPackage, якщо вам потрібно підтримувати XLS. Мені було важко з цим, і врешті перейшов до ExcelLibrary.
Джеремі

Однозначно правда. ExcelPackage / ExML - це лише хороший варіант, якщо вам потрібна підтримка XLSX.
Нейт

5
Зауважте, що ExcelPackage має наступника: EPPlus ( epplus.codeplex.com ), який підтримує XLSX. Моя єдина проблема в порівнянні з NPOI, наприклад, - це продуктивність, наприклад, коли стовпців багато.
Pragmateek

63

Надзвичайно легким варіантом може бути використання таблиць HTML. Просто створіть теги заголовка, тіла та таблиці у файлі та збережіть його як файл із розширенням .xls. Існують специфічні атрибути Майкрософт, які можна використовувати для стилізації результатів, включаючи формули.

Я усвідомлюю, що ви, можливо, не кодуєте це у веб-додатку, але ось приклад складу файлу Excel через таблицю HTML. Цей прийом можна використовувати, якщо ви кодували консольний додаток, настільний додаток чи послугу.


6
Це так ad hoc, але воно працює (не кажучи вже про те, що Excel видає попередження про відкриття) і настільки просте, що воно заслуговує на те, щоб мати місце як рішення. Хоча лише для того, щоб показати, що ви можете експортувати файл excel :))
Лука Рамішвілі

3
Це рішення спрацювало для мене чудово, зауважте, ви не можете використовувати розширення .xlsx
Джилл

Деякі люди в моїй організації не можуть відкрити файли Excel, створені таким чином в Office 2010 і вище. Не знаю, у чому проблема, але мені довелося прокрутити власну OpenXML-реалізацію. (див. відповідь Соггера)
Крістен Хаммак

49

Якщо ви створюєте файли Excel 2007/2010, спробуйте цей проект з відкритим кодом: https://github.com/closedxml/closedxml

Він надає об'єктно-орієнтований спосіб маніпулювання файлами (подібним до VBA), не маючи труднощів з XML-документами. Його можна використовувати будь-якою мовою .NET, як-от C # та Visual Basic (VB).

ClosedXML дозволяє створювати файли Excel 2007/2010 без програми Excel. Типовим прикладом є створення звітів Excel на веб-сервері:

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

9
Я спробував це використати в проекті, який створює досить великі аркуші Excel. Відмінна бібліотека, але надзвичайно погана в роботі. Я щойно зробив порівняння для проекту, над яким я працюю: ClosedXML (v 0.53.3) зайняв 92 489 мс, тоді як EPPlus (v 2.9.03, для тестування - ми не можемо використовувати, оскільки це GPL) зайняв 16 500 мс.
Друїд

1
@Druid ліцензія є LGPL, припускаючи, що ви не змінюєте вихідний код на ClosedXML, вільно використовувати epplus.codeplex.com/license
Chris Marisic


47

Ви насправді можете перевірити класи interop, доступні в C # (наприклад, Microsoft.Office.Interop.Excelви кажете, що немає OLE (що це не так), але інтероп-класи дуже прості у використанні. Ознайомтесь із документацією C # тут (Interop для Excel починається з сторінка 1072 C # PDF).

Ви можете бути вражені, якщо ви не пробували їх.

Будьте попереджені про позицію Microsoft щодо цього:

Наразі Microsoft не рекомендує та не підтримує автоматизацію програм Microsoft Office від будь-якого непридатного клієнтського додатка чи компонента (включаючи ASP, ASP.NET, DCOM та NT Services), оскільки Office може проявляти нестабільну поведінку та / або тупик, коли Office працює в цьому середовищі.


6
Але ви повинні переконатися, що ви все розпоряджаєтесь вручну, інакше ви просочите пам’ять
MagicKat

8
@ Ricky B: Також, на мій досвід роботи з interop, це те, що він використовує excel. Кожен раз, коли ми використовували його, якщо Excel не був встановлений на машині, ми отримували винятки COM.
MagicKat

1
З OLE, навіть при дуже обережних розпорядженнях, це врешті-решт витокує пам’ять або збої. Це, очевидно, нормально для відвідуваних додатків / робочих станцій, але для серверів не рекомендується (MS має КБ, що це говорить). Для нашого сервера ми просто перезавантажуємо його щоночі. Знову ж таки, це працює добре.
Дженніфер Зуак

11
@Geoffrey: ага, ви збираєтесь змусити мене працювати над цим :) -> support.microsoft.com/kb/257757 Microsoft наразі не рекомендує та не підтримує автоматизацію програм Microsoft Office від будь-яких без нагляду, інтерактивна програма для клієнтів ...
Дженніфер Зуак

4
Я приходжу до цього обговорення після того, як більше тижня вживаю інтероп, і якщо ваші потреби не дуже прості, це не спрацює. Підтримка форматування вашої електронної таблиці є ненормальною, що, мабуть, є причиною створення файлу .xls, а не просто плоского .csv-файлу. Наприклад, ви намагалися вивести більше 911 символів у комірку, чи намагалися послідовно задавати ширину об'єднаних комірок? У мене є, і я не можу вам сказати, наскільки я ненавиджу це лайно зараз ... Зробіть собі прихильність і підіть з однією з безкоштовних бібліотек, згаданих на цій дискусії.
md1337

34

Ось абсолютно безкоштовна бібліотека C #, яка дозволяє експортувати з DataSet, DataTableабоList<> в повному Excel 2007 .xlsx файл, використовуючи бібліотеки OpenXml:

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

Повний вихідний код надається безкоштовно - разом із інструкціями та демо-програмою.

Після додавання цього класу до вашої програми ви можете експортувати свій DataSet в Excel лише в одному рядку коду:

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

Це не стає набагато простіше, ніж це ...

І навіть не вимагає, щоб Excel був присутній на вашому сервері.


1
Це здається трохи оманливим, оскільки ви просите пожертву, щоб отримати всі функції.
UrbanEsc

Це частково вірно: абсолютно безкоштовна версія створить для вас ідеальний .xlsx файл, і весь вихідний код надається. Якщо ви даруєте 10 або більше доларів на одну з тих двох благодійних організацій (з яких я не отримую абсолютно нічого), ви отримуєте "кращу" версію, що показує, як робити форматування, дати тощо. Враховуючи вартість сторонніх продуктів, я вважаю пожертвувати 10 доларів на добру справу, натомість варто того варто!
Майк Гледхілл


23

Ви можете поглянути на GemBox.Spreadsheet .

У них є безкоштовна версія з усіма можливостями, але обмежена 150 рядками на аркуші та 5 аркушами на робочу книжку, якщо це відповідає вашим потребам.

Мені ще не потрібно було його використовувати, але виглядає цікаво.


21

Syncfusion Essential XlsIO може це зробити. Він не залежить від офісу Microsoft, а також має конкретну підтримку різних платформ.

Зразок коду:

//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.


18

Добре,

Ви також можете використовувати сторонню бібліотеку типу Aspose .

Ця бібліотека має таку перевагу, що вона не вимагає встановлення Excel на вашій машині, що було б ідеально у вашому випадку.


Якщо точніше, ви можете використовувати Aspose.Cells для .NET для створення файлів Excel (XLS, XLSX) у вашому додатку .NET.
Шахзад Латиф

9
Так, ви можете, якщо ви не заперечуєте проти сплати мінімальної ліцензійної плати в розмірі 999 доларів. Спробуйте бібліотеку MikesKnowledgeBase ... що на 999 доларів дешевше за це !!
Майк Гледхілл

17

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

Перевірте це : OpenXML: Альтернатива, яка допомагає уникнути встановлення MS Excel на сервері


17

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

Що стосується моїх досліджень, то є два комерційні пакети, які дозволяють виводити на старі формати бінарних файлів. Вони є:

Жоден з них не дешевий (я думаю, 500USD і 800USD відповідно). але обидві працюють незалежно від самого Excel.

Мені було б цікаво - це вихідний модуль Excel на зразок OpenOffice.org. Цікаво, чи можна їх перенести з Java на .Net.


Цей працює як на .net, так і на java, і коштує недешево. SmartXLS smartxls.com
лія


15

Я нещодавно використовував FlexCel.NET і виявив, що це відмінна бібліотека! Я цього не кажу про занадто багато програмних продуктів. Тут немає сенсу вказувати весь крок продажів, ви можете ознайомитися з усіма функціями на їхньому веб-сайті.

Це комерційний продукт, але ви отримуєте повне джерело, якщо купуєте його. Тож я припускаю, що ви могли б скласти це до своєї асамблеї, якщо цього дуже хотіли. Інакше це лише одна додаткова збірка до xcopy - ніякої конфігурації чи установки чи нічого подібного.

Я не думаю, що ви не знайдете жодного способу зробити це без сторонніх бібліотек, оскільки .NET Framework, очевидно, не підтримує його, і OLE Automation - це лише цілий світ болю.


15

Я написав простий код для експорту набору даних до 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();
    }

1
Як в статті йдеться, однак, це XML, що Excel буде читати, а не бути файлом XLS, а це означає, що він може працювати лише в Excel, а не в інших програмах, які читають електронні таблиці. Але це, мабуть, краще, ніж відповіді еквівалентної таблиці HTML тут!
Rup

Підтримує xlsx ? OpenXML ?
Кіквенет

14

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

(Відмова: Я працюю в SoftArtisans, компанії, яка виробляє OfficeWriter)



12

Ось спосіб зробити це за допомогою LINQ до XML разом із зразком коду:

Швидкий імпорт та експорт даних Excel за допомогою LINQ в XML

Це трохи складно, оскільки вам доведеться імпортувати простори імен тощо, але це дозволяє уникнути будь-яких зовнішніх залежностей.

(Крім того, звичайно, це VB .NET, а не C #, але ви завжди можете ізолювати речі VB .NET у власному проекті, щоб використовувати XML Literals, а також робити все інше в C #.)


12

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

Оскільки ці постачальники також надають вдосконалені компоненти сітки інтерфейсу користувача, ці компоненти особливо зручні, якщо ви хочете, щоб стиль та компонування експорту excel імітували поточний стан сітки в інтерфейсі користувача вашої програми.

Якщо ваш експорт призначений для виконання на сервері з акцентом на дані, які потрібно експортувати, і не має посилання на користувальницький інтерфейс, я б попровадив один із варіантів безкоштовного відкритого коду (наприклад, ExcelLibrary).

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


12
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, воно може допомогти вам


7
Ні, це генерує HTML, позначений як файл Excel, а не справжній файл Excel. Так, Excel сам відкриє це ОК, але інші програми, які споживають електронні таблиці, включаючи безкоштовний переглядач Excel Microsoft, наприклад, - не приймуть його. Краще вам створити справжній файл Excel, використовуючи одну з бібліотек тут.
Rup

Ви також повинні використовувати System.Net.Mime.ContentDisposition, щоб генерувати текст заголовка диспозиції вмісту, а не додавати рядок - це правильно впорається з назви файлів, що містять пробіли тощо.
Rup

12

Ви можете створити добре відформатовані файли 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};
    }
}

10

Найпростіший і найшвидший спосіб створити файл Excel з C # - це використовувати інструмент Open XML Productivity Tool. Інструмент Open XML Productivity поставляється з установкою 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 на зразок цієї:

введіть тут опис зображення


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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.