如何使用c#将JQgrid数据导出到Excel?
我已经做了一些关于这方面的研究,但大多数的解决scheme是为MVC ..我只是使用Asp.net的3.5我怎么能实现这个button点击..我应该包括任何图书馆或其他..请帮助..
我在答案中发布的代码几乎可以在任何用C#编写的ASP.NET代码中进行修改。 助手类DataForExcel
(请参阅文件DataForExcel.cs
)具有构造函数
public DataForExcel(string[] headers, List<string[]> data, string sheetName)
或多一点“高级”版本
public DataForExcel(string[] headers, DataType[] colunmTypes, List<string[]> data, string sheetName)
它允许指定哪些列具有数字数据types。 参数List<string[]> data
是需要导出到Excel的数据。 参数string[] headers
指定输出的第一行的数据。
DataForExcel
类只有一个公共方法
public void CreateXlsxAndFillData(Stream stream)
用填充的.XLSX Excel文件的二进制表示填充stream
。
为了从你的ASP.NET方法返回二进制数据(例如ASHX处理程序),你只需要做几乎相同的事情从我的答案ExecuteResult
:
-
using (var stream = new MemoryStream()) {...}
创build内存stream - 创build需要导出到Excel的
DataForExcel
对象var dataExcel = new DataForExcel (new []{"Id", "Votes", "Title"}, "Questions.xlsx", "Name or Sheet");
-
response.AddHeader ("content-disposition", "attachment; filename=Questions.xlsx");
-
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
-
response.ContentEncoding = Encoding.UTF8;
-
stream.WriteTo (response.OutputStream);
-
response.Flush();
就是这样
更新 :我修改了我之前发布的代码,以非常简单的方式从网格中创buildExcel文件(以.xlsx格式)。 如果您使用OpenXML SDK 2.0,那么您可以使用.NET 3.5。 OpenXML SDK 2.5需要.NET 4.0或更高版本。
build议的代码允许将数据的string[][]
转换为二进制Excel数据,并将结果写入stream中。 您可以像我之前描述的那样使用MemoryStream
从任何ASP.NET应用程序返回Excel。
build议的代码包含一个带有一个公共静态方法FillSpreadsheetDocument
ExportToExcel
静态类,它可以通过以下方式使用
var data = new[] { new [] {"Tom", "30", "x", "", "1974-06-16"}, new [] {"Margarita", "34", "x", "x", "1978-10-02"}, new [] {"Bob", "7", "", "", "2005-06-26"}, new [] {"Oleg", "48", "x", "x", "1964-09-11"}, new [] {"Frank", "29", "", "x", "1983-01-28"} }; using (var stream = new FileStream("Test.xlsx", FileMode.Create)) { ExportToExcel.FillSpreadsheetDocument(stream, new[] { new ColumnModel { Type = DataType.String, Alignment = HorizontalAlignment.Left, Header = "Name" }, new ColumnModel { Type = DataType.Integer, Header = "Age" }, new ColumnModel { Type = DataType.String, Header = "Is Married", Alignment = HorizontalAlignment.Center, IsRotatedHeader = true }, new ColumnModel { Type = DataType.String, Header = "Has Children", Alignment = HorizontalAlignment.Center, IsRotatedHeader = true }, new ColumnModel { Type = DataType.Date, Header = "Birthday", Alignment = HorizontalAlignment.Left } }, data, "Friends"); }
它会生成一个"Test.xlsx"
并显示一张“朋友”
列的宽度将不会被设置,但是在两次点击(全部select并在列之间双击),用户可以像上面的构build一样将列的宽度设置为最佳宽度。 所有的单元格都有格式化的数据(没有“通用”格式)。 我使用整数,date和纯string。 人们可以很容易地创build中心alignment或右alignment文本的列。
您可以轻松修改代码,以便使用更多不同的文本格式。 这只是一个例子,如何使用格式化的单元格生成真正的Excel文档。
工作Visual Studio 2008项目,您可以从这里下载。 下面你会发现演示的源代码:
using System; using System.Collections.Generic; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Text; using System.IO; using System.Globalization; namespace ExportToExcel { public enum ExcelCellDataType { String, Integer, Date } public enum HorizontalAlignment { Left, Center, Right } public class ColumnModel { public ExcelCellDataType Type { set; get; } public HorizontalAlignment Alignment { set; get; } public string Header { set; get; } public bool IsRotatedHeader { set; get; } } public enum OutputCellFormat: uint { Text, Integer, Date, TextHeader, TextHeaderRotated, TextCenter, TextRight } public static class ExportToExcel { private static StringBuilder ConvertIntToColumnHeader (uint iCol) { var sb = new StringBuilder(); while (iCol > 0) { if (iCol <= 'Z' - 'A') // iCol=0 -> 'A', 25 -> 'Z' break; sb.Append(ConvertIntToColumnHeader(iCol / ('Z' - 'A' + 1) - 1)); iCol = iCol % ('Z' - 'A' + 1); } sb.Append((char)('A' + iCol)); return sb; } private static string GetCellReference (uint iRow, uint iCol) { return ConvertIntToColumnHeader(iCol).Append(iRow).ToString(); } private static Row CreateColumnHeaderRow (uint iRow, IList<ColumnModel> colunmModels) { var r = new Row { RowIndex = iRow }; for (var iCol = 0; iCol < colunmModels.Count; iCol++) { var styleIndex = colunmModels[iCol].IsRotatedHeader ? (UInt32Value)(uint)(OutputCellFormat.TextHeaderRotated + 1) : (UInt32Value)(uint)(OutputCellFormat.TextHeader + 1); r.Append(new OpenXmlElement[] { // create Cell with InlineString as a child, which has Text as a child new Cell(new InlineString(new Text { Text = colunmModels[iCol].Header })) { DataType = CellValues.InlineString, StyleIndex = styleIndex, CellReference = GetCellReference(iRow, (uint)iCol) } }); } return r; } private static UInt32Value GetStyleIndexFromColumnModel (ColumnModel colunmModel) { switch (colunmModel.Type) { case ExcelCellDataType.Integer: return (uint)(OutputCellFormat.Integer) + 1; case ExcelCellDataType.Date: return (uint)(OutputCellFormat.Date) + 1; } switch (colunmModel.Alignment) { case HorizontalAlignment.Center: return (uint)(OutputCellFormat.TextCenter) + 1; case HorizontalAlignment.Right: return (uint)(OutputCellFormat.TextRight) + 1; default: return (uint)(OutputCellFormat.Text) + 1; } } private static string ConvertDateToString (string date) { DateTime dt; string text = date; // default results of conversion if (DateTime.TryParse(date, out dt)) text = dt.ToOADate().ToString(CultureInfo.InvariantCulture); return text; } private static Row CreateRow (UInt32 iRow, IList<string> data, IList<ColumnModel> colunmModels, IDictionary<string, int> sharedStrings) { var r = new Row { RowIndex = iRow }; for (var iCol = 0; iCol < data.Count; iCol++) { var styleIndex = (uint)(OutputCellFormat.Text) + 1; string text = data[iCol] ?? String.Empty; if (colunmModels != null && iCol < colunmModels.Count) { styleIndex = GetStyleIndexFromColumnModel(colunmModels[iCol]); switch (colunmModels[iCol].Type) { case ExcelCellDataType.Integer: r.Append(new OpenXmlElement[] { // create Cell with CellValue as a child, which has Text as a child new Cell(new CellValue { Text = text }) { StyleIndex = styleIndex, CellReference = GetCellReference(iRow, (uint)iCol) } }); continue; case ExcelCellDataType.Date: r.Append(new OpenXmlElement[] { // create Cell with CellValue as a child, which has Text as a child new Cell(new CellValue { Text = ConvertDateToString(text) }) { StyleIndex = styleIndex, CellReference = GetCellReference(iRow, (uint)iCol) } }); continue; } } // default format is text if (String.IsNullOrEmpty(text) || !sharedStrings.ContainsKey(text)) { // create Cell with InlineString as a child, which has Text as a child r.Append(new OpenXmlElement[] { new Cell(new InlineString(new Text { Text = text })) { DataType = CellValues.InlineString, StyleIndex = styleIndex, CellReference = GetCellReference(iRow, (uint)iCol) } }); } else { r.Append(new OpenXmlElement[] { // create Cell with CellValue as a child, which has Text as a child new Cell(new CellValue { Text = sharedStrings[text].ToString(CultureInfo.InvariantCulture) }) { DataType = CellValues.SharedString, StyleIndex = styleIndex, CellReference = GetCellReference(iRow, (uint)iCol) } }); } } return r; } private static void FillSpreadsheetDocument (SpreadsheetDocument spreadsheetDocument, IList<ColumnModel> columnModels, IList<string[]> data, string sheetName) { if (columnModels == null) throw new ArgumentNullException("columnModels"); if (data == null) throw new ArgumentNullException("data"); // add empty workbook and worksheet to the SpreadsheetDocument var workbookPart = spreadsheetDocument.AddWorkbookPart(); var worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>(); // create styles for the header and columns workbookStylesPart.Stylesheet = new Stylesheet( new Fonts( // Index 0 - The default font. new Font( new FontSize { Val = 11 }, new Color { Rgb = new HexBinaryValue { Value = "00000000" } }, new FontName { Val = "Calibri" } ), // Index 1 - The bold font. new Font( new Bold(), new FontSize { Val = 11 }, new Color { Rgb = new HexBinaryValue { Value = "00000000" } }, new FontName { Val = "Calibri" } ) ), new Fills( // Index 0 - required, reserved by Excel - no pattern new Fill(new PatternFill { PatternType = PatternValues.None }), // Index 1 - required, reserved by Excel - fill of gray 125 new Fill(new PatternFill { PatternType = PatternValues.Gray125 }), // Index 2 - no pattern text on gray background new Fill(new PatternFill { PatternType = PatternValues.Solid, BackgroundColor = new BackgroundColor { Indexed = 64U }, ForegroundColor = new ForegroundColor { Rgb = "FFD9D9D9" } }) ), new Borders( // Index 0 - The default border. new Border( new LeftBorder(), new RightBorder(), new TopBorder(), new BottomBorder(), new DiagonalBorder() ), // Index 1 - Applies a Left, Right, Top, Bottom border to a cell new Border( new LeftBorder(new Color { Auto = true }) { Style = BorderStyleValues.Thin }, new RightBorder(new Color { Auto = true }) { Style = BorderStyleValues.Thin }, new TopBorder(new Color { Auto = true }) { Style = BorderStyleValues.Thin }, new BottomBorder(new Color { Auto = true }) { Style = BorderStyleValues.Thin }, new DiagonalBorder() ) ), new CellFormats( // Index 0 - The default cell style. If a cell does not have a style iCol applied it will use this style combination instead new CellFormat { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U }, // Index 1 - Alignment Left, Text new CellFormat(new Alignment { Horizontal = HorizontalAlignmentValues.Left }) { NumberFormatId = (UInt32Value)49U, // "@" - text format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true, ApplyAlignment = true }, // Index 2 - Interger Number new CellFormat { NumberFormatId = (UInt32Value)1U, // "0" - integer format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true }, // Index 3 - Interger Date new CellFormat { NumberFormatId = (UInt32Value)14U, // "14" - date format mm-dd-yy - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true }, // Index 4 - Text for headers new CellFormat(new Alignment { Vertical = VerticalAlignmentValues.Center, Horizontal = HorizontalAlignmentValues.Center }) { NumberFormatId = (UInt32Value)49U, // "@" - text format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)1U, FillId = (UInt32Value)2U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true, ApplyAlignment = true }, // Index 5 - Text for headers rotated new CellFormat(new Alignment { Horizontal = HorizontalAlignmentValues.Center, TextRotation = (UInt32Value)90U }) { NumberFormatId = (UInt32Value)49U, // "@" - text format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)1U, FillId = (UInt32Value)2U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true, ApplyAlignment = true }, // Index 6 - Alignment Center, Text new CellFormat(new Alignment { Horizontal = HorizontalAlignmentValues.Center }) { NumberFormatId = (UInt32Value)49U, // "@" - text format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true, ApplyAlignment = true }, // Index 7 - Alignment Right, Text new CellFormat(new Alignment { Horizontal = HorizontalAlignmentValues.Right }) { NumberFormatId = (UInt32Value)49U, // "@" - text format - see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, ApplyNumberFormat = true, ApplyAlignment = true } ) ); workbookStylesPart.Stylesheet.Save(); // create and fill SheetData var sheetData = new SheetData(); // first row is the header uint iRow = 1; sheetData.AppendChild(CreateColumnHeaderRow(iRow++, columnModels)); //iRow++; // skip one row for the filter // first of all collect all different strings var sst = new SharedStringTable(); var sharedStrings = new SortedDictionary<string, int>(); foreach (var dataRow in data) for (var iCol = 0; iCol < dataRow.Length; iCol++) if (iCol >= columnModels.Count || columnModels[iCol].Type != ExcelCellDataType.Integer) { string text = (columnModels[iCol].Type == ExcelCellDataType.Date ? dataRow[iCol] : ConvertDateToString(dataRow[iCol])) ?? String.Empty; if (!String.IsNullOrEmpty(text) && !sharedStrings.ContainsKey(text)) { sst.AppendChild(new SharedStringItem(new Text(text))); sharedStrings.Add(text, sharedStrings.Count); } } var shareStringPart = workbookPart.AddNewPart<SharedStringTablePart>(); shareStringPart.SharedStringTable = sst; shareStringPart.SharedStringTable.Save(); foreach (var dataRow in data) sheetData.AppendChild(CreateRow(iRow++, dataRow, columnModels, sharedStrings)); // add sheet data to Worksheet worksheetPart.Worksheet = new Worksheet(sheetData); worksheetPart.Worksheet.Save(); // fill workbook with the Worksheet spreadsheetDocument.WorkbookPart.Workbook = new Workbook( new FileVersion { ApplicationName = "Microsoft Office Excel" }, new Sheets(new Sheet { Name = sheetName, SheetId = (UInt32Value)1U, Id = workbookPart.GetIdOfPart(worksheetPart) // generate the id for sheet }) ); spreadsheetDocument.WorkbookPart.Workbook.Save(); spreadsheetDocument.Close(); } public static void FillSpreadsheetDocument (Stream stream, IList<ColumnModel> columnModels, IList<string[]> data, string sheetName) { using (var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook)) { FillSpreadsheetDocument(spreadsheetDocument, columnModels, data, sheetName); } } } class Program { static void Main () { var data = new[] { new [] {"Tom", "30", "x", null, "1974-06-16"}, new [] {"Margarita", "34", "x", "x", null}, new [] {"Bob", "7", "", "", "2005-06-26"}, new [] {"Oleg", null, "x", "x", "1964-09-11"}, new [] {"Frank", "29", "", "x", "1983-01-28"} }; using (var stream = new FileStream("Test.xlsx", FileMode.Create)) { ExportToExcel.FillSpreadsheetDocument(stream, new[] { new ColumnModel { Type = ExcelCellDataType.String, Alignment = HorizontalAlignment.Left, Header = "Name" }, new ColumnModel { Type = ExcelCellDataType.Integer, Header = "Age" }, new ColumnModel { Type = ExcelCellDataType.String, Header = "Is Married", Alignment = HorizontalAlignment.Center, IsRotatedHeader = true }, new ColumnModel { Type = ExcelCellDataType.String, Header = "Has Children", Alignment = HorizontalAlignment.Center, IsRotatedHeader = true }, new ColumnModel { Type = ExcelCellDataType.Date, Header = "Birthday", Alignment = HorizontalAlignment.Left } }, data, "Friends"); } } } }
php + jqgrid +导出为excel
虽然这是一个PHP解决scheme,它的核心似乎是在Javascript中,如果有任何帮助。
您可以使用Office XML格式(http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats)。; 唯一的缺点是输出将是一个XML文件,而不是一个二进制文件。 但是,它的打开方式与正常的.xls文件完全相同。
我以前的做法是以我需要的格式对Excel进行逆向工程,然后将其保存为.xml格式,在Notepad ++中打开它,并找出头,表格(从网格转换而来),最后是页脚
例:
标题(可以硬编码)
<?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> <Author>phpGrid.com</Author> <Created></Created> <LastSaved></LastSaved> <Version></Version> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> <WindowHeight>768</WindowHeight> <WindowWidth>1024</WindowWidth> <WindowTopX>0</WindowTopX> <WindowTopY>0</WindowTopY> <ProtectStructure>False</ProtectStructure> <ProtectWindows>False</ProtectWindows> </ExcelWorkbook> <Styles> <Style ss:ID="Default" ss:Name="Normal"> <Alignment ss:Vertical="Bottom" /> <Borders/> <Font ss:FontName="Arial" ss:Size="8" /> <Interior/> <NumberFormat /> <Protection /> </Style> <Style ss:ID="sHyperlink" ss:Name="Hyperlink"> <Font ss:Color="#0000FF" ss:Underline="Single" /> </Style> <Style ss:ID="sDate"> <NumberFormat ss:Format="Short Date"/> </Style> <Style ss:ID="sNumber"> <NumberFormat/> </Style> <Style ss:ID="sHeader"> <Font ss:Family="Arial" ss:Bold="1" /> </Style> <Style ss:ID="sDecimal"> <NumberFormat ss:Format="Fixed"/> </Style> </Styles><Worksheet ss:Name="Sheet1">
Body(这是从datagrid转换而来的表格,需要dynamic生成)
<Table ss:ExpandedColumnCount="7" ss:ExpandedRowCount="328" x:FullColumns="1" x:FullRows="1"><Row><Cell ss:StyleID="sHeader"><Data ss:Type="String">Order No.</Data></Cell><Cell ss:StyleID="sHeader"><Data ss:Type="String">Order Date</Data></Cell><Cell ss:StyleID="sHeader"><Data ss:Type="String">Shipped Date</Data></Cell><Cell ss:StyleID="sHeader"><Data ss:Type="String">status</Data></Cell><Cell ss:StyleID="sHeader"><Data ss:Type="String">comments</Data></Cell><Cell ss:StyleID="sHeader"><Data ss:Type="String">Customer No.</Data></Cell></Row> <Row><Cell ss:StyleID="sNumber"><Data ss:Type="Number">0</Data></Cell><Cell><Data ss:Type="String">2010-08-20 00:00:00</Data></Cell><Cell><Data ss:Type="String"></Data></Cell><Cell><Data ss:Type="String">Open</Data></Cell><Cell><Data ss:Type="String">foo</Data></Cell><Cell ss:StyleID="sNumber"><Data ss:Type="Number">123456</Data></Cell></Row> <Row><Cell ss:StyleID="sNumber"><Data ss:Type="Number">10100</Data></Cell><Cell><Data ss:Type="String">2003-01-06 00:00:00</Data></Cell><Cell><Data ss:Type="String">2003-01-10 00:00:00</Data></Cell><Cell><Data ss:Type="String">Shipped</Data></Cell><Cell><Data ss:Type="String">foo</Data></Cell><Cell ss:StyleID="sNumber"><Data ss:Type="Number">363</Data></Cell></Row> <Row><Cell ss:StyleID="sNumber"><Data ss:Type="Number">10101</Data></Cell><Cell><Data ss:Type="String">2003-01-18 00:00:00</Data></Cell><Cell><Data ss:Type="String">2003-01-22 00:00:00</Data></Cell><Cell><Data ss:Type="String">Shipped</Data></Cell><Cell><Data ss:Type="String">Check on availability.</Data></Cell><Cell ss:StyleID="sNumber"><Data ss:Type="Number">128</Data></Cell></Row></Table>
页脚(可以硬编码)
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> <Print> <ValidPrinterInfo /> <HorizontalResolution>800</HorizontalResolution> <VerticalResolution>0</VerticalResolution> </Print> <Selected /> <Panes> <Pane> <Number>3</Number> <ActiveRow>1</ActiveRow> </Pane> </Panes> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> </Workbook>
您可以简单地对页眉和页脚XML进行硬编码,只有主体将被dynamic生成。 如果你需要alignment和其他需要的样式。 再次尝试相同的“反向”工程方法,找出需要添加到XML中的东西。
我发现这种方式的一个优点是,您不需要依赖API,因为从字面上看,所有东西都可以被embedded到一个string中。 它也适用于不同的编程语言。 可能不像API那样灵活或强大,但对于数据网格,只有表,行和列是足够的。 至less对于我来说。