Як я можу створити таблицю Excel за допомогою C #, не вимагаючи встановлення Excel на машині, на якій працює код?
Як я можу створити таблицю Excel за допомогою C #, не вимагаючи встановлення Excel на машині, на якій працює код?
Відповіді:
Можна використовувати бібліотеку під назвою ExcelLibrary. Це безкоштовна бібліотека з відкритим кодом, розміщена на Google Code:
Схоже, це порт 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 вручну, але перерахована вище функціональність мене справді вразила.
Якщо ви задоволені форматом xlsx, спробуйте мій проект GitHub, EPPlus . Він розпочався з джерела з ExcelPackage, але сьогодні це повне перезапис. Він підтримує діапазони, стилізацію комірок, діаграми, фігури, зображення, названі діапазони, автофільтр та багато іншого.
А як щодо використання Open XML SDK 2.0 для Microsoft Office?
Кілька переваг:
Посилання:
Я успішно використовував такі проекти з відкритим кодом:
ExcelPackage для форматів OOXML (Office 2007)
NPOI для формату .XLS (Office 2003). NPOI 2.0 (Beta) також підтримує XLSX.
Погляньте на мої повідомлення в блозі:
Ви можете використовувати 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 - Ще кілька посилань:
Комерційне рішення SpreadsheetGear для .NET це зробить.
Ви можете побачити зразки ASP.NET (C # і VB) тут, а завантажити оціночну версію тут .
Відмова: Я є власником SpreadsheetGear LLC
Я використав кілька варіантів:
Якщо XLSX є обов'язковим: ExcelPackage - це хороший старт, але відмирав, коли розробник кинув працювати над ним. ExML взяв звідти і додав кілька функцій. ExML - це не поганий варіант, я все ще використовую його на кількох веб-сайтах з виробництва.
Однак для всіх моїх нових проектів я використовую NPOI , .NET порт AI- POI Apache . NPOI 2.0 (Alpha) також підтримує XLSX.
Надзвичайно легким варіантом може бути використання таблиць HTML. Просто створіть теги заголовка, тіла та таблиці у файлі та збережіть його як файл із розширенням .xls. Існують специфічні атрибути Майкрософт, які можна використовувати для стилізації результатів, включаючи формули.
Я усвідомлюю, що ви, можливо, не кодуєте це у веб-додатку, але ось приклад складу файлу Excel через таблицю HTML. Цей прийом можна використовувати, якщо ви кодували консольний додаток, настільний додаток чи послугу.
Якщо ви створюєте файли 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");
Ви можете використовувати ExcelXmlWriter .
Це чудово працює.
Ви насправді можете перевірити класи 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 працює в цьому середовищі.
Ось абсолютно безкоштовна бібліотека C #, яка дозволяє експортувати з DataSet
, DataTable
абоList<>
в повному Excel 2007 .xlsx файл, використовуючи бібліотеки OpenXml:
http://mikesknowledgebase.com/pages/CSharp/ExportToExcel.htm
Повний вихідний код надається безкоштовно - разом із інструкціями та демо-програмою.
Після додавання цього класу до вашої програми ви можете експортувати свій DataSet в Excel лише в одному рядку коду:
CreateExcelFile.CreateExcelDocument(myDataSet, "C:\\Sample.xlsx");
Це не стає набагато простіше, ніж це ...
І навіть не вимагає, щоб Excel був присутній на вашому сервері.
Ви можете розглянути можливість створення своїх файлів у форматі XML Spreadsheet 2003 . Це простий формат XML з використанням добре задокументованої схеми .
Ви можете поглянути на GemBox.Spreadsheet .
У них є безкоштовна версія з усіма можливостями, але обмежена 150 рядками на аркуші та 5 аркушами на робочу книжку, якщо це відповідає вашим потребам.
Мені ще не потрібно було його використовувати, але виглядає цікаво.
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.
Добре,
Ви також можете використовувати сторонню бібліотеку типу Aspose .
Ця бібліотека має таку перевагу, що вона не вимагає встановлення Excel на вашій машині, що було б ідеально у вашому випадку.
OpenXML також є хорошою альтернативою, яка допомагає уникнути встановлення MS Excel на сервері. Відкритий XML SDK 2.0, що надається Microsoft, спрощує завдання управління пакетами Open XML та основними елементами схеми Open XML в пакеті. Інтерфейс програмного забезпечення Open XML (API) включає в себе безліч поширених завдань, які розробники виконують на Open XML-пакетах.
Перевірте це : OpenXML: Альтернатива, яка допомагає уникнути встановлення MS Excel на сервері
Різні доступні бібліотеки XML Office 2003 досить добре працюють для менших файлів Excel. Однак я вважаю проблемою розмір великої робочої книги, збереженої у форматі XML. Наприклад, робоча книжка, з якою я працюю, складе 40 Мб у новому (і, правда кажучи, більш щільно упакованому) форматі XLSX стає файлом XML 360 Мб.
Що стосується моїх досліджень, то є два комерційні пакети, які дозволяють виводити на старі формати бінарних файлів. Вони є:
Жоден з них не дешевий (я думаю, 500USD і 800USD відповідно). але обидві працюють незалежно від самого Excel.
Мені було б цікаво - це вихідний модуль Excel на зразок OpenOffice.org. Цікаво, чи можна їх перенести з Java на .Net.
Я погоджуюся щодо створення електронних таблиць XML, ось приклад того, як це зробити для C # 3 (всі лише блоги про це в VB 9: P) http://www.aaron-powell.com/linq-to-xml-to- відмінник
Я нещодавно використовував FlexCel.NET і виявив, що це відмінна бібліотека! Я цього не кажу про занадто багато програмних продуктів. Тут немає сенсу вказувати весь крок продажів, ви можете ознайомитися з усіма функціями на їхньому веб-сайті.
Це комерційний продукт, але ви отримуєте повне джерело, якщо купуєте його. Тож я припускаю, що ви могли б скласти це до своєї асамблеї, якщо цього дуже хотіли. Інакше це лише одна додаткова збірка до xcopy - ніякої конфігурації чи установки чи нічого подібного.
Я не думаю, що ви не знайдете жодного способу зробити це без сторонніх бібліотек, оскільки .NET Framework, очевидно, не підтримує його, і OLE Automation - це лише цілий світ болю.
Я написав простий код для експорту набору даних до 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();
}
Просто хочете додати ще одне посилання на рішення третьої сторони, яке безпосередньо стосується вашої проблеми: http://www.officewriter.com
(Відмова: Я працюю в SoftArtisans, компанії, яка виробляє OfficeWriter)
Ось спосіб зробити це за допомогою LINQ до XML разом із зразком коду:
Швидкий імпорт та експорт даних Excel за допомогою LINQ в XML
Це трохи складно, оскільки вам доведеться імпортувати простори імен тощо, але це дозволяє уникнути будь-яких зовнішніх залежностей.
(Крім того, звичайно, це VB .NET, а не C #, але ви завжди можете ізолювати речі VB .NET у власному проекті, щоб використовувати XML Literals, а також робити все інше в C #.)
Деякі постачальники компонентів сторонніх виробників, такі як Infragistics або Syncfusion, забезпечують дуже хороші можливості експорту Excel, які не потребують встановлення Microsoft Excel.
Оскільки ці постачальники також надають вдосконалені компоненти сітки інтерфейсу користувача, ці компоненти особливо зручні, якщо ви хочете, щоб стиль та компонування експорту excel імітували поточний стан сітки в інтерфейсі користувача вашої програми.
Якщо ваш експорт призначений для виконання на сервері з акцентом на дані, які потрібно експортувати, і не має посилання на користувальницький інтерфейс, я б попровадив один із варіантів безкоштовного відкритого коду (наприклад, ExcelLibrary).
Раніше я брав участь у проектах, які намагалися використовувати автоматизацію на серверній стороні в пакеті Microsoft Office. Виходячи з цього досвіду, я настійно рекомендую проти такого підходу.
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, воно може допомогти вам
Ви можете створити добре відформатовані файли 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};
}
}
Найпростіший і найшвидший спосіб створити файл Excel з C # - це використовувати інструмент Open XML Productivity Tool. Інструмент Open XML Productivity поставляється з установкою Open XML SDK. Інструмент реверсує будь-який файл Excel у код C #. Потім код C # може бути використаний для відновлення цього файлу.
Огляд залученого процесу:
DesiredLook.xlsx
.DesiredLook.xlsx
і натисніть кнопку Reflect Code у верхній частині.
Як бонус, цей метод працює для будь-яких файлів Word та PowerPoint. Як розробник C #, ви внесете зміни в код, щоб відповідати вашим потребам.
Я розробив простий додаток WPF на github, який буде працювати для Windows для цієї мети. Існує клас заповнення, який називається, GeneratedClass
куди можна вставити згенерований код. Якщо ви повернетесь до однієї версії файлу, він створить файл excel на зразок цієї:
Деякі корисні автоматизації Excel в C #, u можна знайти за наступним посиланням.
http://csharp.net-informations.com/excel/csharp-excel-tutorial.htm
болтон.
Подивіться на зразки, як створити файли Excel.
Є приклади в C # і VB.NET
Він управляє XSL XSLX та CSV Excel файлами.
xls
абоxlsx
одним із них). Це не вимога, щоб на вашому комп’ютері була програма, яка може її читати (скажімо, бінарну).