initial version with inspection edition
This commit is contained in:
483
IronIntelContractorBusiness/ExportExcel/ExportToExcel.cs
Normal file
483
IronIntelContractorBusiness/ExportExcel/ExportToExcel.cs
Normal file
@@ -0,0 +1,483 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using DocumentFormat.OpenXml;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Data;
|
||||
|
||||
namespace IronIntel.Contractor
|
||||
{
|
||||
internal class ChartFormatedData : IOpenXmlExcelStyleAndData
|
||||
{
|
||||
public ChartFormatedData()
|
||||
{
|
||||
FormatType = CellFormatType.CSharp;
|
||||
}
|
||||
|
||||
#region IOpenXmlExcelStyleAndData Members
|
||||
|
||||
public CellAlignment CAlignment { get; set; }
|
||||
|
||||
public CellBorder CBorder { get; set; }
|
||||
|
||||
public CellFill CFill { get; set; }
|
||||
|
||||
public CellFont CFont { get; set; }
|
||||
|
||||
public CellDataType DataType { get; set; }
|
||||
|
||||
public string FormatCode { get; set; }
|
||||
|
||||
public CellFormatType FormatType { get; set; }
|
||||
|
||||
public object Value { get; set; }
|
||||
|
||||
public String MergedCellsPosition { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ExportToExcel
|
||||
{
|
||||
/// <summary>
|
||||
/// 将DataTable的数据导出到Excel
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] CreateExcel(DataTable data, string caption, double[] columnWidths, string[] MergeTitles)
|
||||
{
|
||||
COpenXmlExcelSheet osheet = ConvertToOpenXmlObject(data, caption, columnWidths, MergeTitles);
|
||||
|
||||
MemoryStream ms = null;
|
||||
try
|
||||
{
|
||||
ms = new MemoryStream();
|
||||
ExcelXlsx xls = new ExcelXlsx();
|
||||
xls.CreatePackage(ms, osheet);
|
||||
ms.Position = 0;
|
||||
|
||||
byte[] bts = new byte[ms.Length];
|
||||
int offset = 0;
|
||||
while (offset < bts.Length)
|
||||
{
|
||||
offset += ms.Read(bts, offset, bts.Length - offset);
|
||||
}
|
||||
|
||||
return bts;
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
if (ms != null)
|
||||
ms.Close();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private object ConvertIvalidChars(object s)
|
||||
{
|
||||
if (s == null) return null;
|
||||
if (s.GetType() != typeof(string)) return s;
|
||||
const string invalidCharsMatch =
|
||||
"(?ims)[\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" +
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f]";
|
||||
|
||||
//取代其中無效字元, 通通換成空字串
|
||||
s = Regex.Replace(
|
||||
s.ToString(),
|
||||
invalidCharsMatch, "");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private COpenXmlExcelSheet ConvertToOpenXmlObject(DataTable data, string caption, double[] columnWidths, string[] MergeTitles)
|
||||
{
|
||||
try
|
||||
{
|
||||
COpenXmlExcelSheet osheet = new COpenXmlExcelSheet();
|
||||
|
||||
// 设置数据和格式。
|
||||
|
||||
//所有数据和格式存放在此结构中。
|
||||
List<List<IOpenXmlExcelStyleAndData>> dataMatrix = new List<List<IOpenXmlExcelStyleAndData>>();
|
||||
osheet.DataMatrix = dataMatrix;
|
||||
|
||||
//行数据临时对象。
|
||||
List<IOpenXmlExcelStyleAndData> rowData = null;
|
||||
//单元格数据临时对象。
|
||||
ChartFormatedData cellData = null;
|
||||
|
||||
DataRow rdr = null;
|
||||
DataColumn rdc = null;
|
||||
|
||||
#region 设置宽度。
|
||||
|
||||
foreach (var w in columnWidths)
|
||||
{
|
||||
osheet.WidthList.Add(w);
|
||||
}
|
||||
//for (int k = 0; k < dataFromClient.Columns.Count; k++)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// rdc = dataFromClient.Columns[k];
|
||||
// if (rdc.Attributes == null || !rdc.Attributes.ContainsKey("Width"))
|
||||
// {
|
||||
// osheet.WidthList.Add(100);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// osheet.WidthList.Add(Convert.ToDouble(rdc.Attributes["Width"]));
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
int rowIndex = 0;
|
||||
|
||||
#region caption
|
||||
|
||||
if (!string.IsNullOrEmpty(caption))
|
||||
{
|
||||
rowData = new List<IOpenXmlExcelStyleAndData>();
|
||||
cellData = new ChartFormatedData();
|
||||
cellData.CAlignment = new CellAlignment();
|
||||
cellData.CAlignment.Align = GetAlignment("center");
|
||||
cellData.DataType = CellDataType.String;
|
||||
cellData.FormatCode = "";
|
||||
|
||||
cellData.CFont = new CellFont();
|
||||
cellData.CFont.FontSize = 14;
|
||||
|
||||
cellData.Value = caption;
|
||||
cellData.MergedCellsPosition = "A1:" + ConvertColNumber(data.Columns.Count) + "1";
|
||||
|
||||
rowData.Add(cellData);
|
||||
rowIndex += 1;
|
||||
dataMatrix.Add(rowData);
|
||||
|
||||
//设置第一行的高度。
|
||||
osheet.RowHeightList.Add(rowIndex, 23);
|
||||
|
||||
//添加一个空行。
|
||||
rowData = new List<IOpenXmlExcelStyleAndData>();
|
||||
cellData = new ChartFormatedData();
|
||||
cellData.MergedCellsPosition = "A2:" + ConvertColNumber(data.Columns.Count) + "2";
|
||||
rowData.Add(cellData);
|
||||
rowIndex += 1;
|
||||
dataMatrix.Add(rowData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MergeTitles
|
||||
|
||||
if (MergeTitles != null && MergeTitles.Length % 2 == 0)
|
||||
{
|
||||
rowData = new List<IOpenXmlExcelStyleAndData>();
|
||||
|
||||
for (int q = 0; q < data.Columns.Count; q++)
|
||||
{
|
||||
cellData = new ChartFormatedData();
|
||||
cellData.CAlignment = new CellAlignment();
|
||||
cellData.CAlignment.Align = GetAlignment("center");
|
||||
cellData.DataType = CellDataType.String;
|
||||
cellData.FormatCode = "";
|
||||
|
||||
cellData.CFont = new CellFont();
|
||||
cellData.CFont.FontSize = 14;
|
||||
|
||||
rowData.Add(cellData);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MergeTitles.Length; i += 2)
|
||||
{
|
||||
string[] tmp = MergeTitles[i + 1].Split('-');
|
||||
if (tmp.Length == 1) continue;
|
||||
|
||||
cellData = (ChartFormatedData)rowData[(Convert.ToInt32(tmp[0]) - 1)];
|
||||
cellData.Value = MergeTitles[i];
|
||||
cellData.MergedCellsPosition = ConvertColNumber(Convert.ToInt32(tmp[0])) + "3:" + ConvertColNumber(Convert.ToInt32(tmp[1])) + "3";
|
||||
}
|
||||
|
||||
rowIndex += 1;
|
||||
dataMatrix.Add(rowData);
|
||||
//设置第一行的高度。
|
||||
osheet.RowHeightList.Add(rowIndex, 15);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region header。
|
||||
|
||||
rowData = new List<IOpenXmlExcelStyleAndData>();
|
||||
|
||||
for (int q = 0; q < data.Columns.Count; q++)
|
||||
{
|
||||
rdc = data.Columns[q];
|
||||
cellData = new ChartFormatedData();
|
||||
|
||||
string alignment = "";
|
||||
if (rdc != null)
|
||||
{
|
||||
//if (rdc.Attributes != null && rdc.Attributes.ContainsKey("Alignment"))
|
||||
//{
|
||||
// alignment = rdc.Attributes["Alignment"];
|
||||
//}
|
||||
|
||||
cellData.CAlignment = new CellAlignment();
|
||||
cellData.CAlignment.Align = GetAlignment(alignment);
|
||||
|
||||
cellData.CFont = new CellFont();
|
||||
cellData.CFont.IsBold = true;
|
||||
|
||||
cellData.CFill = new CellFill();
|
||||
cellData.CFill.FillColor = System.Drawing.Color.Gray;
|
||||
|
||||
cellData.DataType = CellDataType.String;
|
||||
cellData.FormatCode = "";
|
||||
}
|
||||
|
||||
cellData.Value = rdc.ColumnName;
|
||||
|
||||
rowData.Add(cellData);
|
||||
}
|
||||
rowIndex += 1;
|
||||
osheet.RowHeightList.Add(rowIndex, 18);
|
||||
dataMatrix.Add(rowData);
|
||||
|
||||
#endregion
|
||||
|
||||
#region real data 。
|
||||
|
||||
for (int k = 0; k <= data.Rows.Count - 1; k++)
|
||||
{
|
||||
rdr = data.Rows[k];
|
||||
rowData = new List<IOpenXmlExcelStyleAndData>();
|
||||
|
||||
for (int q = 0; q < data.Columns.Count; q++)
|
||||
{
|
||||
rdc = data.Columns[q];
|
||||
|
||||
string format = "";
|
||||
//if (rdc != null)
|
||||
//{
|
||||
//if (rdc.Attributes != null && rdc.Attributes.ContainsKey("DataFormat"))
|
||||
//{
|
||||
// format = (rdc.Attributes["DataFormat"] == null
|
||||
// ? ""
|
||||
// : rdc.Attributes["DataFormat"].ToString());
|
||||
//}
|
||||
//}
|
||||
|
||||
cellData = new ChartFormatedData();
|
||||
|
||||
//将特殊格式值处理成字符串显示。
|
||||
if (rdr != null)
|
||||
{
|
||||
bool isProcessed = false;
|
||||
cellData.Value =
|
||||
ConvertIvalidChars(
|
||||
ProcessSpecialFormat(rdr[q], format, ref isProcessed));
|
||||
if (isProcessed) format = "";
|
||||
}
|
||||
cellData.FormatCode = ProcessFormat(format);
|
||||
cellData.DataType =
|
||||
GetDataType((cellData.Value == null ? typeof(string) : cellData.Value.GetType()));
|
||||
|
||||
string alignment = "";
|
||||
if (rdc != null)
|
||||
{
|
||||
//if (rdc.Attributes != null && rdc.Attributes.ContainsKey("Alignment"))
|
||||
//{
|
||||
// alignment = rdc.Attributes["Alignment"];
|
||||
//}
|
||||
cellData.CAlignment = new CellAlignment();
|
||||
cellData.CAlignment.Align = GetAlignment(alignment);
|
||||
}
|
||||
|
||||
//如果是合计行则以浅灰色显示。
|
||||
//if (hasTotalRow && k == dataFromClient.Rows.Count - 1)
|
||||
//{
|
||||
// cellData.CFill = new CellFill();
|
||||
// cellData.CFill.FillColor = System.Drawing.Color.LightGray;
|
||||
//}
|
||||
|
||||
//如果是合计列则以浅灰色显示。
|
||||
//if (hasTotalColumn && q == dataFromClient.Columns.Count - 1)
|
||||
//{
|
||||
// cellData.CFill = new CellFill();
|
||||
// cellData.CFill.FillColor = System.Drawing.Color.LightGray;
|
||||
//}
|
||||
|
||||
rowData.Add(cellData);
|
||||
}
|
||||
|
||||
//rowIndex += 1;
|
||||
//if (hasTotalRow && k == dataFromClient.Rows.Count - 1)
|
||||
//{
|
||||
// osheet.RowHeightList.Add(rowIndex, totalRowHeight);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// osheet.RowHeightList.Add(rowIndex, 18);
|
||||
//}
|
||||
|
||||
dataMatrix.Add(rowData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return osheet;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private string ConvertColNumber(int colnum)
|
||||
{
|
||||
string zzz = "Z+";
|
||||
Regex reg = new Regex(zzz);
|
||||
string result = "";
|
||||
MatchCollection mc = null;
|
||||
for (int k = 0; k < colnum; k++)
|
||||
{
|
||||
mc = reg.Matches(result);
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
//是zzz格式。
|
||||
string first = result.Substring(0, mc[0].Index);
|
||||
if (string.IsNullOrEmpty(first))
|
||||
{
|
||||
result = result.Replace("Z", "A") + "A";
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = first[first.Length - 1];
|
||||
c = Convert.ToChar(c + 1);
|
||||
result = c.ToString() + result.Substring(mc[0].Index).Replace("Z", "A");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(result))
|
||||
{
|
||||
result = "A";
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = result[result.Length - 1];
|
||||
c = Convert.ToChar(c + 1);
|
||||
result = result.Substring(0, result.Length - 1) + c.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Alignment GetAlignment(string align)
|
||||
{
|
||||
Alignment horizon = new Alignment() { Horizontal = HorizontalAlignmentValues.Left, WrapText = true };
|
||||
|
||||
if (string.Equals(align, "center", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
horizon = new Alignment() { Horizontal = HorizontalAlignmentValues.Center, WrapText = true };
|
||||
}
|
||||
else if (string.Equals(align, "right", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
horizon = new Alignment() { Horizontal = HorizontalAlignmentValues.Right, WrapText = true };
|
||||
}
|
||||
|
||||
return horizon;
|
||||
}
|
||||
|
||||
private CellDataType GetDataType(Type typ)
|
||||
{
|
||||
CellDataType result = CellDataType.String;
|
||||
|
||||
switch (Type.GetTypeCode(typ))
|
||||
{
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.UInt64:
|
||||
result = CellDataType.Integer;
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.Single:
|
||||
result = CellDataType.Float;
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
result = CellDataType.Date;
|
||||
break;
|
||||
case TypeCode.Boolean:
|
||||
result = CellDataType.Bool;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private object ProcessSpecialFormat(object val, string format, ref bool isProcessed)
|
||||
{
|
||||
object result = val;
|
||||
isProcessed = false;
|
||||
if (val == null || string.IsNullOrEmpty(format.Trim())) return result;
|
||||
|
||||
CellDataType typ = GetDataType(result.GetType());
|
||||
|
||||
//第一个特殊格式:如果值是6位字符串,格式是"MMM-yyyy",则按日期处理。
|
||||
if (typ == CellDataType.String && string.Equals(format.Replace(" ", ""), "{0:MMM-yyyy}"))
|
||||
{
|
||||
string str = result.ToString();
|
||||
if (str.Length == 6)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = new DateTime(Convert.ToInt32(str.Substring(0, 4)), Convert.ToInt32(str.Substring(4)), 1);
|
||||
result = string.Format(format, result);
|
||||
isProcessed = true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 处理Format格式,使一些特殊符号(如:*、@)可以直接在Excel中看到,而不是解释成Excel中对这些符号的定义
|
||||
/// </summary>
|
||||
/// <param name="format">格式字符串</param>
|
||||
/// <returns></returns>
|
||||
private string ProcessFormat(string format)
|
||||
{
|
||||
string resultFormat = format;
|
||||
if (string.IsNullOrEmpty(resultFormat)) return resultFormat;
|
||||
if (format.IndexOf("*") >= 0)
|
||||
{
|
||||
resultFormat = resultFormat.Replace("*", "\"*\"");
|
||||
}
|
||||
if (format.IndexOf("@") >= 0)
|
||||
{
|
||||
resultFormat = resultFormat.Replace("@", "\"@\"");
|
||||
}
|
||||
return resultFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user