在C#中使用.net3.0和Openxml在服务器端实现数据格式转换成OpenxmlExcel

日前公司要求实现将data table中的数据转换成Excel文件格式提供给用户下载,几经周折,试过很多中方法,终于找到一个相对比较好的解决方案,虽然不够漂亮,但是基本上实现了这个需求。
1 。安装。Net3.0 ,下载 Openxml.dll
这些都是可以从微软的网站上免费获得。

2。可以做使用Excel2007做一个模板,设置好style,这样可以很方便。如果自己生成新的Excel文件的话,也可以,不过要深入研究OpenXml的格式。
3。具体的转换代码(需要改动
4。在具体的使用中,使用stream的方式提供给用户下载。代码如下:
(1)调用代码
 DataTable dt = .........

            string parentFolderPath = Server.MapPath("Excel");
            if (dt == null) return;
            ORE.BusinessLogic.TransferToExcel transfer = new ORE.BusinessLogic.TransferToExcel();
            byte[] results = transfer.TransferToOpenXMLExcelByStream(parentFolderPath, dt, ViewState["Option"].ToString());
            if (results != null)
            {
                Response.ClearContent();
                Response.ContentType = "application/x-zip-compressed";  //this is very important
                Response.ContentEncoding = System.Text.Encoding.UTF8;
                Response.AddHeader("Content-Disposition", "attachment;filename=" + LabelTitle.Text.Replace(" ", "") + ".xlsx");
                Response.BinaryWrite(results);
                Response.Flush();
                Response.Close();
            }
            else
            {
                string errorMessage = "Transfer process terminated unexpectedly, please contact the ORE Helpdesk";
                Response.Write("<script language='javascript'>alert('" + errorMessage + "');</script>");
            }
(2) transferring code

using System;
using System.Data;
using System.Configuration;
using System.Web;
using Microsoft.Office.DocumentFormat.OpenXml.Packaging;
using System.IO.Packaging;
using System.IO;
using System.Data.SqlClient;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Text;


    /// <summary>
    /// Transfer the data to the OpenXML Excel format
    /// Added by zhailei 2007-12-24
    /// needs to add WindowsBase and OpenXml references
    /// </summary>
    struct OutputColumn
    {
        private string _colName;
        private string _outputColName;
        private int _outputColWidth;
        public string ColumnName
        {
            get
            {
                return _colName;
            }
        }
        public string OutputColumnName
        {
            get
            {
                return _outputColName;
            }
        }
        public int OutputColWidth
        {
            get
            {
                return _outputColWidth;
            }
        }
        public OutputColumn(string colName, string outputColName):this(colName,outputColName,10)
        {
           
        }
        public OutputColumn(string colName, string outputColName, int outputColWidth)
        {
            this._colName = colName;
            this._outputColName = outputColName;
            this._outputColWidth = outputColWidth;
        }
    }
    public class TransferToExcel
    {
        public byte[] TransferToOpenXMLExcelByStream(string parentFolderPath, DataTable data,string option)
        {
            //template file
            string filePath = parentFolderPath + @"/template.xlsx";
            FileInfo file = new FileInfo(filePath);
            if (!file.Exists)
            {
                return null;
            }
            //read the template file to a byte[] buffer
            byte[] srcFileBuffer;
            using (FileStream srcFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                srcFileBuffer = new byte[srcFileStream.Length];
                srcFileStream.Read(srcFileBuffer, 0, (int)srcFileStream.Length);
            }
            byte[] resultFileBuffer;
            using (MemoryStream workStream = new MemoryStream())
            {
                workStream.Write(srcFileBuffer, 0, srcFileBuffer.Length);
                if (OpenXlsDocumentByStream(workStream, data,option) == true)
                {
                    resultFileBuffer = new byte[workStream.Length];
                    workStream.Seek(0, SeekOrigin.Begin);
                    workStream.Read(resultFileBuffer, 0, (int)workStream.Length);
                    return resultFileBuffer;
                }
                else
                    return null;
            }
        }
        private bool OpenXlsDocumentByStream(MemoryStream workStream, DataTable data,string option)
        {
            try
            {
                using (SpreadsheetDocument xlDoc = SpreadsheetDocument.Open(workStream, true))
                {
                    if (xlDoc == null) return false;

                    //find fromOre sheet               
                    const string worksheetNamespace = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
                    XmlDocument doc = new XmlDocument();
                    doc.Load(xlDoc.WorkbookPart.GetStream());
                    XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
                    nsManager.AddNamespace("d", doc.DocumentElement.NamespaceURI);
                    nsManager.AddNamespace("w", worksheetNamespace);
                    string searchString = string.Format("//d:sheet[@name='{0}']", "FromORE"); //FromORE is according to the template file
                    XmlNode sheetNode = doc.SelectSingleNode(searchString, nsManager);
                    if (sheetNode == null) return false;

                    //  Get the relationship id attribute:
                    XmlAttribute relationAttribute = sheetNode.Attributes["r:id"];
                    if (relationAttribute == null) return false;
                    string relId = relationAttribute.Value;

                    // loads its contents as XML:
                    WorksheetPart worksheetPart = (WorksheetPart)xlDoc.WorkbookPart.GetPartById(relId);
                    if (InsertNewData(worksheetPart, data, nsManager,option) == true)
                    {
                        doc.Save(xlDoc.WorkbookPart.GetStream(FileMode.Create));
                        return true;
                    }
                    else
                        return false;
                }
            }
            catch
            {
                return false;
            }
        }
        private bool InsertNewData(WorksheetPart part, DataTable data, XmlNamespaceManager nsManager,string option)
        {
            XmlDocument sheetDoc = new XmlDocument();
            sheetDoc.Load(part.GetStream());       
            // Get the columns' name of output columns           
            OutputColumn[] outputColumns = GetOutputColumns(option);
            string worksheetNamespace = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
            //set the columns' width           
            XmlNode sheetCols = sheetDoc.SelectSingleNode("//w:cols", nsManager);
            if (sheetCols == null) return false;
            int colIndex;
            for (int i = 0; i < outputColumns.Length; i++)
            {
                colIndex = i + 1;
                string xpath = @"./w:col[@min='" + colIndex.ToString() + "']";
                XmlNode colNode = sheetCols.SelectSingleNode(xpath, nsManager);
                if (colNode != null)
                {
                    colNode.Attributes["width"].Value = outputColumns[i].OutputColWidth.ToString();
                }
                else
                {
                    XmlNode newColNode = sheetDoc.CreateElement("col", worksheetNamespace);
                    colIndex = i + 1;
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("min"));
                    newColNode.Attributes["min"].Value = colIndex.ToString();
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("max"));
                    newColNode.Attributes["max"].Value = colIndex.ToString();
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("style"));
                    newColNode.Attributes["style"].Value = "1";
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("width"));
                    newColNode.Attributes["width"].Value = outputColumns[i].OutputColWidth.ToString();
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("bestFit"));
                    newColNode.Attributes["bestFit"].Value = "1";
                    newColNode.Attributes.Append(sheetDoc.CreateAttribute("customWidth"));
                    newColNode.Attributes["customWidth"].Value = "1";
                    sheetCols.AppendChild(newColNode);
                }
            }
            //Get the sheetData node
            XmlNode sheetDataNode = sheetDoc.SelectSingleNode("//w:sheetData", nsManager);
            //sheetDataNode is not found
            if (sheetDataNode == null)
                return false;
            // Columns' Name in row 1           
            XmlNode ColRowNode = sheetDoc.CreateElement("row", worksheetNamespace);
            ColRowNode.Attributes.Append(sheetDoc.CreateAttribute("r"));
            ColRowNode.Attributes["r"].Value = "1";
            ColRowNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
            ColRowNode.Attributes["s"].Value = "2";
            for (int col = 0; col < outputColumns.Length; col++)
            {
                //create a new cell node
                XmlNode newCellNode = sheetDoc.CreateElement("c", worksheetNamespace);
                newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                newCellNode.Attributes["s"].Value = "5"; //titel style
                newCellNode.Attributes.Append(sheetDoc.CreateAttribute("t"));
                newCellNode.Attributes["t"].Value = "inlineStr";
                // set the cell value
                XmlNode newCellValueNode = sheetDoc.CreateElement("is", worksheetNamespace);
                XmlNode newCellValueNode1 = sheetDoc.CreateElement("t", worksheetNamespace);
                newCellValueNode1.InnerText = outputColumns[col].OutputColumnName;
                //set the relations of all the  created nodes
                newCellValueNode.AppendChild(newCellValueNode1);
                newCellNode.AppendChild(newCellValueNode);
                ColRowNode.AppendChild(newCellNode);
            }
            sheetDataNode.AppendChild(ColRowNode);
            //insert the data from row 2
            for (int row = 0; row < data.Rows.Count; row++)
            {
                XmlNode newRowNode = sheetDoc.CreateElement("row", worksheetNamespace);
                for (int col = 0; col < outputColumns.Length; col++)
                {
                    XmlNode newCellNode = sheetDoc.CreateElement("c", worksheetNamespace);
                    XmlNode newCellValueNode;
                    XmlNode newCellValueNode1;
                    switch (outputColumns[col].OutputColumnName)
                    {
                        case "ORE ID":
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                            newCellNode.Attributes["s"].Value = "6";  //normal style
                            newCellValueNode = sheetDoc.CreateElement("v", worksheetNamespace);
                            newCellValueNode.InnerText = (data.Rows[row][outputColumns[col].ColumnName] == null) ? "" : data.Rows[row][outputColumns[col].ColumnName].ToString();
                            newCellNode.AppendChild(newCellValueNode);
                            newRowNode.AppendChild(newCellNode);
                            break;
                        case "Product Revenue":                       
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                            newCellNode.Attributes["s"].Value = "4";// currency style
                            newCellValueNode = sheetDoc.CreateElement("v", worksheetNamespace);
                            if (data.Rows[row][outputColumns[col].ColumnName] != null)
                            {
                                decimal temp = (decimal)data.Rows[row][outputColumns[col].ColumnName];
                                newCellValueNode.InnerText = temp.ToString("F0");
                            }
                            else
                            {
                                newCellValueNode.InnerText = "0";
                            }
                            newCellNode.AppendChild(newCellValueNode);
                            newRowNode.AppendChild(newCellNode);
                            break;
                        case "Create Date":
                        case "Requested Start Date":
                        case "Oppty Due Date":
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                            newCellNode.Attributes["s"].Value = "2";  //date style
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("t"));
                            newCellNode.Attributes["t"].Value = "inlineStr";
                            newCellValueNode = sheetDoc.CreateElement("is", worksheetNamespace);
                            newCellValueNode1 = sheetDoc.CreateElement("t", worksheetNamespace);
                            if (data.Rows[row][outputColumns[col].ColumnName] == null)
                            {
                                newCellValueNode1.InnerText = "";
                            }
                            else
                            {
                                DateTime temp = (DateTime)data.Rows[row][outputColumns[col].ColumnName];
                                newCellValueNode1.InnerText = temp.ToString("MM/dd/yyyy");
                            }
                            newCellValueNode.AppendChild(newCellValueNode1);
                            newCellNode.AppendChild(newCellValueNode);
                            newRowNode.AppendChild(newCellNode);
                            break;
                        case "Notes":
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                            newCellNode.Attributes["s"].Value = "3";//with wrapText style
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("t"));
                            newCellNode.Attributes["t"].Value = "inlineStr";
                            newCellValueNode = sheetDoc.CreateElement("is", worksheetNamespace);
                            newCellValueNode1 = sheetDoc.CreateElement("t", worksheetNamespace);
                            newCellValueNode1.InnerText = (data.Rows[row][outputColumns[col].ColumnName] == null) ? "" : data.Rows[row][outputColumns[col].ColumnName].ToString();
                            //set the relations of all the  created nodes
                            newCellValueNode.AppendChild(newCellValueNode1);
                            newCellNode.AppendChild(newCellValueNode);
                            newRowNode.AppendChild(newCellNode);
                            break;
                        default:
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("s"));
                            newCellNode.Attributes["s"].Value = "6"; 
                            newCellNode.Attributes.Append(sheetDoc.CreateAttribute("t"));
                            newCellNode.Attributes["t"].Value = "inlineStr";
                            newCellValueNode = sheetDoc.CreateElement("is", worksheetNamespace);
                            newCellValueNode1 = sheetDoc.CreateElement("t", worksheetNamespace);
                            newCellValueNode1.InnerText = (data.Rows[row][outputColumns[col].ColumnName] == null) ? "" : data.Rows[row][outputColumns[col].ColumnName].ToString();
                            //set the relations of all the  created nodes
                            newCellValueNode.AppendChild(newCellValueNode1);
                            newCellNode.AppendChild(newCellValueNode);
                            newRowNode.AppendChild(newCellNode);
                            break;

                    }
                }
                sheetDataNode.AppendChild(newRowNode);
            }
            // Save the worksheet part.
            Stream st = part.GetStream(FileMode.Create);
            sheetDoc.Save(st);
            return true;
        }
        /// <summary>
        /// get the index of outputting columns
        /// </summary>
        private OutputColumn[] GetOutputColumns(string option)
        {
            int num;
            switch (option)
            {
                case "ViewByTST":
                case "ViewByTeamSpecialist":
                    num = 21;
                    break;
                default :
                    num = 19;
                    break;
            }
            OutputColumn[] outputColumns = new OutputColumn[num];
            outputColumns[0] = new OutputColumn("OppID", "ORE ID",8);
            outputColumns[1] = new OutputColumn("SiebelID", "Oppty ID",10);
            outputColumns[2] = new OutputColumn("Status", "Status",10);
            outputColumns[3] = new OutputColumn("RequestName", "Request Name",20);
            outputColumns[4] = new OutputColumn("Company", "Company",20);
            outputColumns[5] = new OutputColumn("Segment", "Segment",20);
            outputColumns[6] = new OutputColumn("STUTeamName", "Team",20);
            outputColumns[7] = new OutputColumn("PreSalesOffering", "Activity",30);

            outputColumns[8] = new OutputColumn("SiebelWorkloadType", "Primary Workload Type",20);
            outputColumns[9] = new OutputColumn("SiebelWorkloadDetail", "Primary Workload Detail",20);

            outputColumns[10] = new OutputColumn("SiebelProductRevenue", "Product Revenue");
            outputColumns[11] = new OutputColumn("SiebelDueDate", "Oppty Due Date");
            outputColumns[12] = new OutputColumn("SiebelSalesStage", "Sales Stage Request");
            outputColumns[13] = new OutputColumn("CurrencySalesStage", "Sales Stage Current",15);
            outputColumns[14] = new OutputColumn("Impact", "Sales Stage Change");  //This column has condition format,so if adapted the order of the column,the template.xlsx need to be adjusted too
            outputColumns[15] = new OutputColumn("Originator", "Requestor");
            outputColumns[16] = new OutputColumn("STUSpecialist", "Specialist",15);
            outputColumns[17] = new OutputColumn("CreateDate", "Create Date");
            if (num == 19)
                outputColumns[18] = new OutputColumn("Notes", "Notes",100);
            else
            {
                outputColumns[18] = new OutputColumn("RequestedStartDate", "Requested Start Date");
                outputColumns[19] = new OutputColumn("Duration", "Duration");
                outputColumns[20] = new OutputColumn("Notes", "Notes",100);
            }
            return outputColumns;
        }

    }


你可能感兴趣的:(.net,String,服务器,C#,null,OpenXml)