大家好我想尝试以mvc3中的表格的形式将一些数据导出到excel。这是我用来生成excel文件的类:
//------------------------------------------------------------------------------
// <copyright file="ExcelDocument.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <summary>The Export to Excel Document class.</summary>
// ----------------------------------------------------------------------------
namespace ExporToExcel.Controllers.ControllerExtensions
{
using System;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Extensions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
/// <summary>
/// Excel document.
/// </summary>
public static class ExcelDocument
{
/// <summary>
/// Default spread sheet name.
/// </summary>
private const string DefaultSheetName = "Sheet1";
/// <summary>
/// Create the exel document for streaming.
/// </summary>
/// <param name="documentName">Excel file name.</param>
/// <param name="excelWorkSheetName">Excel worksheet name: default: sheet1.</param>
/// <param name="rowData">Row data to write.</param>
/// <param name="headerData">Header data.</param>
/// <param name="rowPointers">Row pointers.</param>
/// <returns>Memory stream.</returns>
public static MemoryStream Create(string documentName, string excelWorkSheetName, IQueryable rowData, string[] headerData, string[] rowPointers)
{
return CreateSpreadSheet(documentName, excelWorkSheetName, rowData, headerData, rowPointers, null);
}
/// <summary>
/// Create the spreadsheet.
/// </summary>
/// <param name="documentName">Excel file name.</param>
/// <param name="excelWorkSheetName">Excel worksheet name: default: sheet1.</param>
/// <param name="rowData">Row data to write.</param>
/// <param name="headerData">Header data.</param>
/// <param name="rowPointers">Row pointers.</param>
/// <param name="styleSheet">Style sheet.</param>
/// <returns>Memory stream.</returns>
private static MemoryStream CreateSpreadSheet(string documentName, string excelWorkSheetName, IQueryable rowData, string[] headerData, string[] rowPointers, Stylesheet styleSheet)
{
int rowNum = 0;
int colNum = 0;
int maxWidth = 0;
int minCol = 1;
int maxCol = rowPointers == null ? minCol : rowPointers.Length;
maxCol = maxCol == 1 && headerData == null ? 1 : headerData.Length;
MemoryStream xmlStream = SpreadsheetReader.Create();
SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(xmlStream, true);
SetSheetName(excelWorkSheetName, spreadSheet);
if (styleSheet == null)
{
SetStyleSheet(spreadSheet);
}
else
{
spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet = styleSheet;
spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet.Save();
}
WorksheetPart worksheetPart = SpreadsheetReader.GetWorksheetPartByName(spreadSheet, excelWorkSheetName);
WriteHeaders(headerData, out rowNum, out colNum, out maxWidth, spreadSheet, worksheetPart);
AddCellWidthStyles(Convert.ToUInt32(minCol), Convert.ToUInt32(maxCol), maxWidth, spreadSheet, worksheetPart);
if (rowPointers == null || rowPointers.Length == 0)
{
WriteRowsFromHeaders(rowData, headerData, rowNum, out maxWidth, spreadSheet, worksheetPart);
}
else
{
WriteRowsFromKeys(rowData, rowPointers, rowNum, out maxWidth, spreadSheet, worksheetPart);
}
// Save to the memory stream
SpreadsheetWriter.Save(spreadSheet);
spreadSheet.Close();
spreadSheet.Dispose();
return xmlStream;
}
/// <summary>
/// Set the name of the spreadsheet.
/// </summary>
/// <param name="excelSpreadSheetName">Spread sheet name.</param>
/// <param name="spreadSheet">Spread sheet.</param>
private static void SetSheetName(string excelSpreadSheetName, SpreadsheetDocument spreadSheet)
{
excelSpreadSheetName = excelSpreadSheetName ?? DefaultSheetName;
Sheet ss = spreadSheet.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == DefaultSheetName).SingleOrDefault<Sheet>();
ss.Name = excelSpreadSheetName;
}
/// <summary>
/// Add cell width styles.
/// </summary>
/// <param name="minCol">Minimum column index.</param>
/// <param name="maxCol">Maximum column index.</param>
/// <param name="maxWidth">Maximum column width.</param>
/// <param name="spreadSheet">Spread sheet.</param>
/// <param name="workSheetPart">Work sheet.</param>
private static void AddCellWidthStyles(uint minCol, uint maxCol, int maxWidth, SpreadsheetDocument spreadSheet, WorksheetPart workSheetPart)
{
Columns cols = new Columns(new Column() { Min = minCol, Max = maxCol, Width = maxWidth});
workSheetPart.Worksheet.InsertBefore<Columns>(cols, workSheetPart.Worksheet.GetFirstChild<SheetData>());
}
/// <summary>
/// Set the style sheet.
// Note: Setting the style here rather than passing it in ensures that all worksheets will have a common user interface design.
/// </summary>
/// <param name="spreadSheet">Spread sheet to change.</param>
private static void SetStyleSheet(SpreadsheetDocument spreadSheet)
{
// Note: Setting the style here rather than passing it in ensures that all worksheets will have a common user interface design.
Stylesheet styleSheet = spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet;
styleSheet.Fonts.AppendChild(
new Font(new FontSize() { Val = 11 }, new Color() { Rgb = "FFFFFF" }, new FontName() { Val = "Arial" }));
styleSheet.Fills.AppendChild(new Fill()
{
PatternFill = new PatternFill()
{
PatternType = PatternValues.Solid,
BackgroundColor = new BackgroundColor() { Rgb = "D8D8D8" }
}
});
spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet.Save();
}
/// <summary>
/// Save the styl for worksheet headers.
/// </summary>
/// <param name="cellLocation">Cell location.</param>
/// <param name="spreadSheet">Spreadsheet to change.</param>
/// <param name="workSheetPart">Worksheet to change.</param>
private static void SeatHeaderStyle(string cellLocation, SpreadsheetDocument spreadSheet, WorksheetPart workSheetPart)
{
Stylesheet styleSheet = spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet;
Cell cell = workSheetPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference == cellLocation).FirstOrDefault();
if (cell == null)
{
throw new ArgumentNullException("Cell not found");
}
cell.SetAttribute(new OpenXmlAttribute("", "s", "", "1"));
OpenXmlAttribute cellStyleAttribute = cell.GetAttribute("s", "");
CellFormats cellFormats = spreadSheet.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats;
// pick tthe first cell format.
CellFormat cellFormat = (CellFormat)cellFormats.ElementAt(0);
CellFormat cf = new CellFormat(cellFormat.OuterXml);
cf.FontId = styleSheet.Fonts.Count;
cf.FillId = styleSheet.Fills.Count;
cf.Alignment.Horizontal = HorizontalAlignmentValues.General;
cellFormats.AppendChild(cf);
int a = (int)styleSheet.CellFormats.Count.Value;
cell.SetAttribute(cellStyleAttribute);
cell.StyleIndex = styleSheet.CellFormats.Count;
workSheetPart.Worksheet.Save();
}
/// <summary>
/// Replace special characters.
/// </summary>
/// <param name="value">Value to input.</param>
/// <returns>Value with special characters replaced.</returns>
private static string ReplaceSpecialCharacters(string value)
{
value = value.Replace("’", "'");
value = value.Replace("“", "\"");
value = value.Replace("”", "\"");
value = value.Replace("–", "-");
value = value.Replace("…", "...");
return value;
}
/// <summary>
/// Write values to the spreadsheet.
/// </summary>
/// <param name="cellLocation">Row Column Value.</param>
/// <param name="strValue">Value to write.</param>
/// <param name="spreadSheet">Spreadsheet to write to. </param>
/// <param name="workSheet">Worksheet to write to. </param>
private static void WriteValues(string cellLocation, string strValue, SpreadsheetDocument spreadSheet, WorksheetPart workSheet)
{
WorksheetWriter workSheetWriter = new WorksheetWriter(spreadSheet, workSheet);
int intValue = 0;
if (strValue.Contains("$"))
{
strValue = strValue.Replace("$", "");
strValue = strValue.Replace(",", "");
workSheetWriter.PasteValue(cellLocation, strValue, CellValues.Number);
}
else if (int.TryParse(strValue, out intValue))
{
workSheetWriter.PasteValue(cellLocation, strValue, CellValues.Number);
}
else if (string.IsNullOrEmpty(strValue))
{
workSheetWriter.PasteText(cellLocation, strValue);
}
else
{
workSheetWriter.PasteText(cellLocation, strValue);
}
}
/// <summary>
/// Write the excel rows for the spreadsheet.
/// </summary>
/// <param name="rowData">Excel row values.</param>
/// <param name="rowDataKeys">Excel row-key values.</param>
/// <param name="rowNum">Row number.</param>
/// <param name="maxWidth">Max width.</param>
/// <param name="spreadSheet">Spreadsheet to write to. </param>
/// <param name="workSheet">Worksheet to write to. </param>
private static void WriteRowsFromKeys(IQueryable rowData, string[] rowDataKeys, int rowNum, out int maxWidth, SpreadsheetDocument spreadSheet, WorksheetPart workSheet)
{
maxWidth = 0;
foreach (object row in rowData)
{
int colNum = 0;
foreach (string rowKey in rowDataKeys)
{
string strValue = row.GetType().GetProperty(rowKey).GetValue(row, null).ToString();
strValue = ReplaceSpecialCharacters(strValue);
maxWidth = strValue.Length > maxWidth ? strValue.Length : maxWidth;
string cellLocation = string.Format("{0}{1}", GetColumnLetter(colNum.ToString()), rowNum);
ExcelDocument.WriteValues(cellLocation, strValue, spreadSheet, workSheet);
colNum++;
}
rowNum++;
}
}
/// <summary>
/// Convert column number to alpha numeric value.
/// </summary>
/// <param name="colNumber">Column number.</param>
/// <returns>ASCII value for number.</returns>
private static string GetColumnLetter(string colNumber)
{
if (string.IsNullOrEmpty(colNumber))
{
throw new ArgumentNullException(colNumber);
}
string colName = null;
try
{
for (int i = 0; i < colNumber.Length; i++)
{
string colValue = colNumber.Substring(i, 1);
int asc = Convert.ToInt16(colValue) + 65;
colName += Convert.ToChar(asc);
}
}
finally
{
colName = colName ?? "A";
}
return colName;
}
/// <summary>
/// Write the values for the rows from headers.
/// </summary>
/// <param name="rowData">Excel row values.</param>
/// <param name="headerData">Excel header values.</param>
/// <param name="rowNum">Row number.</param>
/// <param name="maxWidth">Max width.</param>
/// <param name="spreadSheet">Spreadsheet to write to. </param>
/// <param name="workSheet">Worksheet to write to. </param>
private static void WriteRowsFromHeaders(IQueryable rowData, string[] headerData, int rowNum, out int maxWidth, SpreadsheetDocument spreadSheet, WorksheetPart workSheet)
{
WorksheetWriter workSheetWriter = new WorksheetWriter(spreadSheet, workSheet);
maxWidth = 0;
foreach (object row in rowData)
{
int colNum = 0;
foreach (string header in headerData)
{
string strValue = row.GetType().GetProperty(header).GetValue(row, null).ToString();
strValue = ReplaceSpecialCharacters(strValue);
maxWidth = strValue.Length > maxWidth ? strValue.Length : maxWidth;
string cellLocation = string.Format("{0}{1}", GetColumnLetter(colNum.ToString()), rowNum);
ExcelDocument.WriteValues(cellLocation, strValue, spreadSheet, workSheet);
colNum++;
}
rowNum++;
}
}
/// <summary>
/// Write the excel headers for the spreadsheet.
/// </summary>
/// <param name="headerData">Excel header values.</param>
/// <param name="rowNum">Row number.</param>
/// <param name="colNum">Column Number.</param>
/// <param name="maxWidth">Max column width</param>
/// <param name="spreadSheet">Maximum Column Width to write to. </param>
/// <param name="workSheet">Worksheet to write to. </param>
private static void WriteHeaders(string[] headerData, out int rowNum, out int colNum, out int maxWidth, SpreadsheetDocument spreadSheet, WorksheetPart workSheet)
{
rowNum = 1;
colNum = 0;
maxWidth = 0;
foreach (string header in headerData)
{
string strValue = ReplaceSpecialCharacters(header);
string cellLocation = string.Format("{0}{1}", GetColumnLetter(colNum.ToString()), rowNum);
maxWidth = strValue.Length > maxWidth ? strValue.Length : maxWidth;
maxWidth = strValue.Length+25;
ExcelDocument.WriteValues(cellLocation, strValue, spreadSheet, workSheet);
SeatHeaderStyle(cellLocation, spreadSheet, workSheet);
colNum++;
}
rowNum++;
}
}
}
我的问题是我在表格中得到了所有文字左对齐。我希望它对齐。此外,表格中的列标题还有黑色背景。我也想改变它的颜色。如何在任何单元格中提供一些硬编码文本?任何帮助将不胜感激。谢谢你
答案 0 :(得分:8)
不是在代码绑定中生成表的列和标题,而是为它创建一个View,以便您可以轻松地向标题和列添加内嵌样式。
在
中添加新课程public class DownloadFileActionResult : ActionResult
{
public string ExcelGridView { get; set; }
public string fileName { get; set; }
public DownloadFileActionResult(string gv, string pFileName)
{
ExcelGridView = gv;
fileName = pFileName;
}
public override void ExecuteResult(ControllerContext context)
{
//Create a response stream to create and write the Excel file
HttpContext curContext = HttpContext.Current;
curContext.Response.Clear();
curContext.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
curContext.Response.Charset = "";
curContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
curContext.Response.ContentType = "application/ms-excel";
//Open a memory stream that you can use to write back to the response
byte[] byteArray = Encoding.ASCII.GetBytes(ExcelGridView);
MemoryStream s = new MemoryStream(byteArray);
StreamReader sr = new StreamReader(s, Encoding.Unicode);
//Write the stream back to the response
curContext.Response.ContentEncoding = System.Text.Encoding.Unicode;
curContext.Response.Write(sr.ReadToEnd());
curContext.Response.End();
}
}
继承自 ActionResult ,接受两个参数之一是您在字符串格式中的查看,另一个是 Excel-filename 。
//In Controller
public ActionResult SaveExcel()
{
string html = RenderPartialViewToString("PartailViewName", model);
// if your view don't have any model then you can pass as null
html = html.Replace("\n", "");
html = html.Replace("\r", "");
html = html.Replace(" ", "");
return new DownloadFileActionResult(html, "ExcelSheetName.xls");
}
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
返回类型的PartialView是 MvcHtmlString 你可以在控制器中获取它,所以我返回一个方法 RenderPartialViewToString 接受两个参数一个是 PartailView 另一个是模型,它将返回部分视图的RenderHtmlString。
创建局部视图
//PartailViewName.cshtml
<table>
<tr>
<th style="background-color:Gray;">
Column1
</th>
<th style="background-color:Gray;">
Column1
</th>
</tr>
<tr>
<td>
Coulmn data
</td>
<td>
Coulmn data
</td>
</tr>
</table>
注意:视图必须是部分视图2)您的所有数据必须仅以表结构排列3)仅提供内嵌样式。