热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

通用的web系统数据导出功能设计实现(导出excel2003/2007wordpdfzip等)

转自:http:www.cnblogs.comxqinp3165258.html前言我们在做web系统中,导出也是很常用的一个功能,如果每一个数据列表都要对应写一个导出的方法不太现

转自:http://www.cnblogs.com/xqin/p/3165258.html

前言

我们在做web系统中,导出也是很常用的一个功能,如果每一个数据列表都要对应写一个导出的方法不太现实。现在就想设计一个共通的功能来实现这个导出。

需求分析

在开始之前我们先要明白我们要实现怎样一个功能 
1、支持导出excel2003/excel2007 word pdf等文件格式 
2、支持数据分页,可以导出全部页或指定页 
3、支持导出的文档再压缩zip rar 7z 
4、支持导出多行的题头 
5、支持格式化,如将 0、1 转换为 男、女 
5、可拓展、可自定义等 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

 

技术分析设计

1、生成文件基本可以使用开源的组件实现 
excel2003 使用 NPOI (有网友提醒我npoi已经支持2007了,我这里暂时还是只处理2003) 
excel2007 使用 EPPlus 
word        使用 DocX 还可以使用直接使用html table导出假的word 
pdf          使用 Gios Pdf 
其它格式预留接口…


2、B/S系统要分前后台,先看前台设计 
可以定义一个共通的js方法如com.exporter那么我们前台使用时应该要可以这样用:

com.exporter(grid)         把grid对象传递给前台导出对象,取得题头的相关信息及grid的url和queryParams传给后台重新取数据
     .paging(2,20)         分页处理表示每页20条,导出第2页,如果第两个参数为0则表示不分页
     .compress('zip’)      文件生成之后压缩成zip文件
     .download(‘xlsx’);    导出excel2007格式的文件

设计成这样基本足够,但是有可能我的grid中没有exporter需要的信息,不能直接com.exporter(grid)这种写法,或者大家不喜欢linq的这种写法,我们再设计另一种参数的写法:

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
com.exporter({
    fileType:’xls’,
    compressType:’none’,
    dataGetter:’api’,                   因为我们数据基本要到后台重新取数据,所以怎么取数据可能有很多种方法,dataGetter就是定义用哪一种方式取数据
    dataUrl:’/mms/api/recive’           接下来的dataUrl及dataParams都是dataGetter=‘api’中用到的参数
    dataParams:{BillNo:’20130701’,Supplier:’huawei’,page:1,rows:0},
    titles: [[]]                        多行的表头数据,跟easyui的多行表头格式设计一致
}).download();
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

那么前台基本就可以这样,有了这两种写法,使用起来就很方便了。


3、后台部分设计 
同样我们从调用的地方入手,在我的下载请求的方法中入手:

    new Exporter()
        .Data(new ApiData())                      定义数据取得方式
        .AddFormatter("sex",new SexFormatter())   添加sex列的formatter
        .Export(new PdfExport())                  设置导出pdf
        .Compress(new ZipCompress())              压缩为zip
        .Download();                              下载文件向浏览器输出

我们要设计一个Exporter的类,它下面有Data Export Compress 等方法 
因为这些东西变动性很大,我取数据不能写死是怎么取的,所以我们定义一个取数据的接口来实现 
比如Exporter的Data方法

public Exporter Data(IDataGetter data)
{
 
}

我在具体取数据的方法中继承IDataGetter接口并实现

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
public class ApiData : IDataGetter
{
    public object GetData(HttpContext context)
    {
        ....
        return data;
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

这样的话,假如我的取数据方式不太一样,我只要 new Exporter().Data(new XXDataGetter())就行了 
同样导出Export方法也一样,我定义了一个接口

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
    public interface IExport
    {
        string suffix { get;}
 
        void MergeCell(int x1,int y1,int x2,int y2);
        void FillData(int x, int y,string field, object data);

        void Init(object data);
        Stream SaveAsStream();

        void SetHeadStyle(int x1, int y1, int x2, int y2);
        void SetRowsStyle(int x1, int y1, int x2, int y2);
    }
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

然后在 XlsExport XlsxExporter DocExporter PdfExporter中实现这个接口就可,然后就可以实现导出不同格式的文档的 
压缩方法Comress及字段格式化方法AddFormatter都同样定义接口,同样有人也不喜欢Exporter的写法,那我们再定义一种和前台差不的写法

    new Exporter()
        .Data("api")
        .Export("xlsx")
        .Compress("zip")
        .Download();

这样的话后台这个exporter类也挺好用的了,那么接下来我们再来谈谈如何具体实现吧

 

技术实现

设计时我们先实现后台 
一、后台其实我已经实现出来了,截个图给大家看看先 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等) 
1、首先我们定义一些基本的元素 
定义题头结构

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
    public class Column
    {
        public Column()
        {
            rowspan = 1;
            colspan = 1;
        }
        public string field { get; set; }
        public string title { get; set; }
        public int rowspan { get; set; }
        public int colspan { get; set; }
        public bool hidden { get; set; }
    }
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

定义压缩接口

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Zephyr.Core
{
    public interface ICompress
    {
        string Suffix(string orgSuffix);
        Stream Compress(Stream fileStream,string fullName);
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

定义数据获取的接口

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System.Web;

namespace Zephyr.Core
{
    public interface IDataGetter
    {
        object GetData(HttpContext context);
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

定义文件导出的接口

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System.IO;

namespace Zephyr.Core
{
    public interface IExport
    {
        string suffix { get;}
 
        void MergeCell(int x1,int y1,int x2,int y2);
        void FillData(int x, int y,string field, object data);

        void Init(object data);
        Stream SaveAsStream();

        void SetHeadStyle(int x1, int y1, int x2, int y2);
        void SetRowsStyle(int x1, int y1, int x2, int y2);
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

定义格式化接口

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
namespace Zephyr.Core
{
    public interface IFormatter
    {
        object Format(object value);
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

 

2、基本的元素都定义好了,我们再来实现Exporter导出类,关键性的代码就在这里了

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using Newtonsoft.Json;
using Zephyr.Utils;

namespace Zephyr.Core
{
    public class Exporter
    {
        const string DEFAULT_EXPORT = "xls";
        const string DEFAULT_DATAGETTER = "api";
        const string DEFAULT_COMPRESS = "none";

        private Dictionary _compress = new Dictionary() { 
            { "zip", typeof(ZipCompress)},
            {"none",typeof(NoneCompress)}
        };
        private Dictionary _dataGetter = new Dictionary() { 
            { "api", typeof(ApiData) } 
        };
        private Dictionary _export = new Dictionary() { 
            { "xls", typeof(XlsExport) }, 
            { "xlsx", typeof(XlsxExport) } ,
            { "doc", typeof(HtmlDocExport) },
            { "pdf", typeof(PdfExport) }
        };

        private Dictionary _fieldFormatter = new Dictionary();

        private object _data;
        private List> _title;
        private Stream _fileStream = null;
        private string _fileName = string.Empty;
        private string _suffix = string.Empty;

        public static Exporter Instance()
        {
            var export = new Exporter();
            var cOntext= HttpContext.Current;

            if (context.Request.Form["titles"]!=null)
                export.Title(JsonConvert.DeserializeObject>>(context.Request.Form["titles"]));

            if (context.Request.Form["dataGetter"] != null)
                export.Data(context.Request.Form["dataGetter"]);

            if (context.Request.Form["fileType"] != null)
                export.Export(context.Request.Form["fileType"]);

            if (context.Request.Form["compressType"] != null)
                export.Compress(context.Request.Form["compressType"]);
 
            return export;
        }
 
        public Exporter Data(IDataGetter data)
        {
            _data = data.GetData(HttpContext.Current);
            return this;
        }
 
        public Exporter Data(string type)
        {
            var dataGetter = GetActor(_dataGetter, DEFAULT_DATAGETTER,type);
            return Data(dataGetter);
        }

        public Exporter Data(object data)
        {
            _data = data;
            return this;
        }

        public Exporter AddFormatter(string field,IFormatter formatter)
        {
            _fieldFormatter[field] = formatter;
            return this;
        }

        public Exporter Title(List> title)
        {
            _title = title;
            return this;
        }

        public Exporter FileName(string fileName)
        {
            _fileName = fileName;
            return this;
        }

        public Exporter Export(string type)
        {
            var export = GetActor(_export, DEFAULT_EXPORT, type);
            return Export(export);
        }

        public Exporter Export(IExport export)
        {
            if (_title == null)
            {
                _title = new List>();
                _title.Add(new List());
                EachHelper.EachListHeader(_data, (i, field, type) => _title[0].Add(new Column() { title = field, field = field, rowspan = 1, colspan = 1 }));
            }
 
            Dictionary currentHeadRow = new Dictionary();
            Dictionary> fieldIndex = new Dictionary>();
            Func GetCurrentHeadRow = cell => currentHeadRow.ContainsKey(cell) ? currentHeadRow[cell] : 0;
            var currentRow = 0;
            var currentCell = 0;

            export.Init(_data);

            //生成多行题头
            for (var i = 0; i <_title.Count; i++)
            {
                currentCell = 0;

                for (var j = 0; j <_title[i].Count; j++)
                {
                    var item = _title[i][j];
                    if (item.hidden) continue;

                    while (currentRow  2)
                        export.MergeCell(currentCell, currentRow, currentCell + item.colspan - 1, currentRow + item.rowspan - 1);

                    if (!string.IsNullOrEmpty(item.field))
                    {
                        if (!fieldIndex.ContainsKey(item.field))
                            fieldIndex[item.field] = new List();
                        fieldIndex[item.field].Add(currentCell);
                    }

                    for (var k = 0; k  dataCount++);
            export.SetRowsStyle(0, currentRow, currentCell - 1, currentRow + dataCount - 1);

            //填充数据
            EachHelper.EachListRow(_data, (rowIndex, rowData) =>
            {
                EachHelper.EachObjectProperty(rowData, (i, name, value) =>
                {
                    if (fieldIndex.ContainsKey(name))
                        foreach (int cellIndex in fieldIndex[name])
                        {
                            if (_fieldFormatter.ContainsKey(name)) 
                                value = _fieldFormatter[name](value);
                            export.FillData(cellIndex, currentRow, name, value);
                        }
                });
                currentRow++;
            });
           
            _fileStream = export.SaveAsStream();

            _suffix = export.suffix;
            if (string.IsNullOrEmpty(_fileName))
                _fileName = DateTime.Now.ToString("yyyyMMddHHmmss");
            
            return this;
        }

        public Exporter Compress(string type)
        {
            var compress = GetActor(_compress, DEFAULT_COMPRESS, type);
            return Compress(compress);
        }

        public Exporter Compress(ICompress compress)
        {
            _fileStream = compress.Compress(_fileStream,string.Format("{0}.{1}",_fileName,_suffix));
            _suffix = compress.Suffix(_suffix);
            return this;
        }

        public void Download()
        {
            if (_fileStream != null && _fileStream.Length > 0)
                ZFiles.DownloadFile(HttpContext.Current, _fileStream, string.Format("{0}.{1}",_fileName,_suffix), 1024 * 1024 * 10);
        }
 
        private T GetActor(Dictionary dict, string defaultKey, string key)
        {
            if (!dict.ContainsKey(key))
                key = defaultKey;

            return (T)Activator.CreateInstance(dict[key]);
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

 

3、Exporter类实现之后我们还要实现一些接口才能使用 
我们这里就先实现 
IDataGetter   ApiData 
IExport         XlsxExport XlsExport HtmlDocExport PdfExport 
IComresss     ZipCompress 
其它的以后再实现就可以了,很方便 

ApiData

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Dynamic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;

namespace Zephyr.Core
{
    public class ApiData : IDataGetter
    {
        public object GetData(HttpContext context)
        {
            dynamic data = null;
            var url = context.Request.Form["dataAction"];
            var param = JsonConvert.DeserializeObject(context.Request.Form["dataParams"]);

            var route = url.Replace("/api/", "").Split('/'); // route[0]=mms,route[1]=send,route[2]=get
            var type = Type.GetType(String.Format("Zephyr.Areas.{0}.Controllers.{1}ApiController,Zephyr.Web", route), false, true);
            if (type != null)
            {
                var instance = Activator.CreateInstance(type);

                var action = route.Length > 2 ? route[2] : "Get";
                var methodInfo = type.GetMethod(action);
                var parameters = new object[] { new RequestWrapper().SetRequestData(param) };
                data = methodInfo.Invoke(instance, parameters);

                if (data.GetType() == typeof(ExpandoObject))
                {
                    if ((data as ExpandoObject).Where(x => x.Key == "rows").Count() > 0)
                        data = data.rows;
                }
            }

            return data;
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)


XlsxExport 导出excel2007 利用 Epplus实现

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Drawing;
using Zephyr.Utils;
using Zephyr.Utils.EPPlus;
using Zephyr.Utils.EPPlus.Style;

namespace Zephyr.Core
{
    public class XlsxExport:IExport
    {
        public string suffix { get {return "xlsx"; } }
 
        private ExcelPackage package;
        private ExcelWorksheet sheet;

        public void Init(object data)
        {
            package = new ExcelPackage();
            sheet = package.Workbook.Worksheets.Add("sheet1");
        }

        public void MergeCell(int x1,int y1,int x2,int y2)
        {
            sheet.Cells[y1+1, x1+1, y2+1, x2+1].Merge = true;
        }

        public virtual void FillData(int x, int y,string field, object value)
        {
            if (ZGeneric.IsTypeIgoreNullable(value))
                sheet.Cells[y + 1, x + 1].Style.Numberformat.Format = "yyyy-MM-dd hh:mm:ss";
            sheet.Cells[y + 1, x + 1].Value = value;
        }

        public virtual void SetHeadStyle(int x1, int y1, int x2, int y2)
        {
            using (var head = sheet.Cells[y1 + 1, x1 + 1, y2 + 1, x2 + 1]) // set head style
            {
                head.Style.Font.Bold = true;
                head.Style.Font.Size = 12;
                head.Style.Font.Name = "Arial";

                head.Style.Border.Top.Style = ExcelBorderStyle.Thin;
                head.Style.Border.Top.Color.SetColor(Color.Gray);
                head.Style.Border.Right.Style = ExcelBorderStyle.Thin;
                head.Style.Border.Right.Color.SetColor(Color.Gray);
                head.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                head.Style.Border.Bottom.Color.SetColor(Color.Gray);
                head.Style.Border.Left.Style = ExcelBorderStyle.Thin;
                head.Style.Border.Left.Color.SetColor(Color.Gray);

                head.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                head.Style.HorizOntalAlignment= ExcelHorizontalAlignment.Center;
                head.Style.Fill.PatternType = ExcelFillStyle.Solid;
                head.Style.Fill.BackgroundColor.SetColor(Color.LightBlue);
            }
        }

        public virtual void SetRowsStyle(int x1, int y1, int x2, int y2)
        {
            using (var data = sheet.Cells[y1 + 1, x1 + 1, y2 + 1, x2 + 1])// set data style
            {
                data.Style.Font.Name = "Arial";
                data.Style.Font.Size = 11;

                data.Style.Border.Top.Style = ExcelBorderStyle.Thin;
                data.Style.Border.Top.Color.SetColor(Color.Gray);
                data.Style.Border.Right.Style = ExcelBorderStyle.Thin;
                data.Style.Border.Right.Color.SetColor(Color.Gray);
                data.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                data.Style.Border.Bottom.Color.SetColor(Color.Gray);
                data.Style.Border.Left.Style = ExcelBorderStyle.Thin;
                data.Style.Border.Left.Color.SetColor(Color.Gray);
            }
        }

        public Stream SaveAsStream()
        {
            var ms = new MemoryStream();
            package.SaveAs(ms);

            package = null;
            sheet = null;
            return ms;
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)


XlsExport 导出excel2003 利用NPOI实现

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System.IO;
using Zephyr.Utils;
using Zephyr.Utils.NPOI.HSSF.UserModel;
using Zephyr.Utils.NPOI.SS.UserModel;
using Zephyr.Utils.NPOI.HSSF.Util;
using Zephyr.Utils.NPOI.SS.Util;

namespace Zephyr.Core
{
    public class XlsExport:IExport
    {
        public string suffix { get {return "xls"; } }

        private HSSFWorkbook workbook;
        private ISheet sheet;

        public void Init(object data)
        {
            workbook = new HSSFWorkbook();
            sheet = workbook.CreateSheet("sheet1");
            sheet.DefaultRowHeight = 200 * 20;
        }

        public void MergeCell(int x1,int y1,int x2,int y2)
        {
            CellRangeAddress range = new CellRangeAddress(y1, y2, x1, x2);
            sheet.AddMergedRegion(range);  
        }

        public virtual void FillData(int x, int y,string field, object value)
        {
            var row = sheet.GetRow(y) ?? sheet.CreateRow(y);
            var cell = row.GetCell(x) ?? row.CreateCell(x);
            switch ((value ?? string.Empty).GetType().Name.ToLower())
            {
                case "int32":
                case "int64":
                case "decimal":
                    cell.CellStyle.Alignment = HorizontalAlignment.RIGHT;
                    cell.SetCellValue(ZConvert.To(value, 0));
                    break;
                default:
                    cell.SetCellValue(ZConvert.ToString(value));
                    break;
            }
        }

        public virtual void SetHeadStyle(int x1, int y1, int x2, int y2)
        {
            var style = GetHeadStyle();
            for (var y = y1; y <= y2; y++)
            {
                var row = sheet.GetRow(y) ?? sheet.CreateRow(y);
                for (var x = x1; x <= x2; x++)
                {
                    var cell = row.GetCell(x) ?? row.CreateCell(x);
                    cell.CellStyle = style;
                }
            }
        }

        public virtual void SetRowsStyle(int x1, int y1, int x2, int y2)
        {
            var style = GetDataStyle();
            for (var y = y1; y <= y2; y++)
            {
                var row = sheet.GetRow(y) ?? sheet.CreateRow(y);
                for (var x = x1; x <= x2; x++)
                {
                    var cell = row.GetCell(x) ?? row.CreateCell(x);
                    cell.CellStyle = style;
                }
            }
        }

        public Stream SaveAsStream()
        {
            var ms = new MemoryStream();
            workbook.Write(ms);
            ms.Flush();
            ms.Position = 0;

            workbook = null;
            sheet = null;
            return ms;
        }

        private ICellStyle GetHeadStyle()
        {
            //表头样式
            var headStyle = workbook.CreateCellStyle();
            headStyle.Alignment = HorizontalAlignment.CENTER;//居中对齐
            headStyle.VerticalAlignment = VerticalAlignment.CENTER;

            //表头单元格背景色
            headStyle.FillForegroundColor = HSSFColor.LIGHT_GREEN.index;
            headStyle.FillPattern = FillPatternType.SOLID_FOREGROUND;
            //表头单元格边框
            headStyle.BorderTop = BorderStyle.THIN;
            headStyle.TopBorderColor = HSSFColor.BLACK.index;
            headStyle.BorderRight = BorderStyle.THIN;
            headStyle.RightBorderColor = HSSFColor.BLACK.index;
            headStyle.BorderBottom = BorderStyle.THIN;
            headStyle.BottomBorderColor = HSSFColor.BLACK.index;
            headStyle.BorderLeft = BorderStyle.THIN;
            headStyle.LeftBorderColor = HSSFColor.BLACK.index;
            //表头字体设置
            var fOnt= workbook.CreateFont();
            font.FOntHeightInPoints= 12;//字号
            font.Boldweight = 600;//加粗
            //font.Color = HSSFColor.WHITE.index;//颜色
            headStyle.SetFont(font);

            return headStyle;
        }

        private ICellStyle GetDataStyle()
        {
            //数据样式
            var dataStyle = workbook.CreateCellStyle();
            dataStyle.Alignment = HorizontalAlignment.LEFT;//左对齐
            //数据单元格的边框
            dataStyle.BorderTop = BorderStyle.THIN;
            dataStyle.TopBorderColor = HSSFColor.BLACK.index;
            dataStyle.BorderRight = BorderStyle.THIN;
            dataStyle.RightBorderColor = HSSFColor.BLACK.index;
            dataStyle.BorderBottom = BorderStyle.THIN;
            dataStyle.BottomBorderColor = HSSFColor.BLACK.index;
            dataStyle.BorderLeft = BorderStyle.THIN;
            dataStyle.LeftBorderColor = HSSFColor.BLACK.index;
            //数据的字体
            var datafOnt= workbook.CreateFont();
            datafont.FOntHeightInPoints= 11;//字号
            dataStyle.SetFont(datafont);

            return dataStyle;
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)


PdfExport 利用Gios pdf实现

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using Zephyr.Utils;
using Zephyr.Utils.Gios.Pdf;
using System.Data;

namespace Zephyr.Core
{
    public class PdfExport:IExport
    {
        public string suffix { get {return "pdf"; } }

        private DataTable table;
        private List title;

        public void Init(object data)
        {
            
            var type = ZGeneric.GetGenericType(data);
            var tableName = ZGeneric.IsDynamicType(type) ? string.Empty : type.Name;
            
            table = new DataTable(tableName);
            EachHelper.EachListHeader(data, (rowIndex, name, cellType) =>
            {
                string typeName = cellType.ToString();
                if (cellType.IsGenericType)
                    typeName = cellType.GetGenericArguments()[0].ToString();

                Type newType = Type.GetType(typeName, false);
                if (newType != null)
                    table.Columns.Add(name, newType);
            });
            table.BeginLoadData();
            title = new List();
        }

        public void MergeCell(int x1,int y1,int x2,int y2)
        {
            throw new Exception("pdf未实现多选title");
        }

        public virtual void FillData(int x, int y,string field, object value)
        {
            if (field.StartsWith("title_"))
            {
                title.Add(field.Split('_')[1]);
                return;
            }

            if (table.Rows.Count();
            foreach (DataColumn dc in table.Columns)
                if (title.IndexOf(dc.ColumnName) == -1)                    
removes.Add(dc.ColumnName);
foreach(var name in removes)
table.Columns.Remove(name);
            var pdfTitle = table.TableName;

            // Starting instantiate the document.
            // Remember to set the Docuement Format. In this case, we specify width and height.
            PdfDocument myPdfDocument = new PdfDocument(PdfDocumentFormat.InCentimeters(21, 29.7));

            // Now we create a Table of 100 lines, 6 columns and 4 points of Padding.
            PdfTable myPdfTable = myPdfDocument.NewTable(new Font("Arial", 12), table.Rows.Count, table.Columns.Count, 4);

            // Importing datas from the datatables... (also column names for the headers!)
            //myPdfTable.ImportDataTable(Table);
            myPdfTable.ImportDataTable(table);

            // Sets the format for correct date-time representation
            //myPdfTable.Columns[2].SetContentFormat("{0:dd/MM/yyyy}");

            // Now we set our Graphic Design: Colors and Borders...
            myPdfTable.HeadersRow.SetColors(Color.White, Color.Navy);
            myPdfTable.SetColors(Color.Black, Color.White, Color.Gainsboro);
            myPdfTable.SetBorders(Color.Black, 1, BorderType.CompleteGrid);

            //// With just one method we can set the proportional width of the columns.
            //// It's a "percentage like" assignment, but the sum can be different from 100.
            //myPdfTable.SetColumnsWidth(new int[] { 5, 25, 16, 20, 20, 15 });

            //// You can also set colors for a range of cells, in this case, a row:
            //myPdfTable.Rows[7].SetColors(Color.Black, Color.LightGreen);

            // Now we set some alignment... for the whole table and then, for a column.
            myPdfTable.SetContentAlignment(ContentAlignment.MiddleCenter);
            myPdfTable.Columns[1].SetContentAlignment(ContentAlignment.MiddleLeft);

            // Here we start the loop to generate the table...
            while (!myPdfTable.AllTablePagesCreated)
            {
                // we create a new page to put the generation of the new TablePage:
                PdfPage newPdfPage = myPdfDocument.NewPage();
                PdfTablePage newPdfTablePage = myPdfTable.CreateTablePage(new PdfArea(myPdfDocument, 48, 120, 500, 670));

                // we also put a Label 
                PdfTextArea pta = new PdfTextArea(new Font("Arial", 26, FontStyle.Bold), Color.Red
                    , new PdfArea(myPdfDocument, 0, 20, 595, 120), ContentAlignment.MiddleCenter, pdfTitle);

                // nice thing: we can put all the objects in the following lines, so we can have
                // a great control of layer sequence... 
                newPdfPage.Add(newPdfTablePage);
                newPdfPage.Add(pta);

                // we save each generated page before start rendering the next.
                newPdfPage.SaveToDocument();
            }

            //myPdfDocument.SaveToFile("Example1.pdf");
            var stream = new MemoryStream();
            myPdfDocument.SaveToStream(stream);
            return stream;
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)


HtmlDocExport 导出word 这个是直接导出html table,不是真正的word,如果要用真正的word要利用DocX来实现,我还没来的及写,以后再贴出来吧

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Zephyr.Core
{
    public class HtmlDocExport:IExport
    {
        public string suffix { get {return "doc"; } }

        private StringBuilder sBuilder;
        private int rowIndex;
        private Dictionary row; 

        public void Init(object data)
        {
            rowIndex = 0;
            row = new Dictionary();
            sBuilder = new StringBuilder();
            sBuilder.Append("");
            sBuilder.Append("");
        }

        public void MergeCell(int x1,int y1,int x2,int y2)
        {
            throw new Exception("htmldoc未实现多选title");
        }

        public virtual void FillData(int x, int y,string field, object value)
        {
            if (rowIndex  m.Key).Select(m => m.Value).ToArray());
                row = new Dictionary();
                rowIndex++;
            }

            row[x] = value;
        }

        public virtual void SetHeadStyle(int x1, int y1, int x2, int y2)
        {
           
        }

        public virtual void SetRowsStyle(int x1, int y1, int x2, int y2)
        {
            
        }

        public Stream SaveAsStream()
        {
            AppendRow(row.OrderBy(m => m.Key).Select(m => m.Value).ToArray());
            sBuilder.Append("");
            foreach(var value in values)
                sBuilder.Append(string.Format("", value??string.Empty ));
            sBuilder.Append("");
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

ZipCompress利用Ionic.Zip实现压缩

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Zephyr.Utils.Ionic.Zip;

namespace Zephyr.Core
{
    public class ZipCompress: ICompress
    {
        public string Suffix(string orgSuffix)
        {
            return "zip";
        }

        public Stream Compress(Stream fileStream,string fullName)
        {
            using (var zip = new ZipFile())
            {
                zip.AddEntry(fullName, fileStream);
                Stream zipStream = new MemoryStream();
                zip.Save(zipStream);
                return zipStream;
            }
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

Formatter实现示例

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
using System;

namespace Zephyr.Core
{
    public class SexFormatter:IFormatter
    {
        public object Format(object value)
        {
            switch(Convert.ToString(value))
            {
                case "0":
                    return "纯爷们";
                case "1":
                    return "女汉子";
                default:
                    return "春哥";
            }
        }
    }
}
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

 

实现了以上这样接口,那么这个Exporter类的功能基本就OK了,如果要拓展一些其它格式以及自定义一些只要实现这些接口就可以,使用很方便了。 
那么我们就应用吧,MVC 及webform都可以,我使用的是mvc,在HomeController下添加一个Download的Action,只要添加一句代码就可以实现了

public void Download()
{
    Exporter.Instance().Download();
}

除了在设计中说的到那些功能,这个Instance方法要再说一下,可以参照Exporter中的代码看,Instance中我有去请求中取参数titles dataGetter fileType compressType等参数并且实现。所以下载action中只需要这么简单的一句代码就搞定了。我们继续看前台吧

二、前台实现 
前台只有一段共通的脚本,很简单

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
com.exporter = function (opt) {
    var self = this;

    var defaultOptiOns= {
        action: "/home/download",
        dataGetter: "api",
        dataAction: "",
        dataParams: {},
        titles: [[]],
        fileType: 'xls',
        compressType: 'none'
    };
 
    this.paging = function (page,rows) {
        self.params.dataParams.page = page;
        self.params.dataParams.rows = rows;
        return self;
    };

    this.compress = function () {
        self.params.compressType = 'zip';
        return self;
    };

    this.title = function (filed,title) {
        self.params.titles[0][filed] = title;
        return self;
    };

    this.download = function (suffix) {
        self.params.fileType = suffix || "xls";
        self.params.dataParams = JSON.stringify(self.params.dataParams);
        self.params.titles = JSON.stringify(self.params.titles);
        var downloadHelper = $('').appendTo('body')[0];
        var doc = downloadHelper.contentWindow.document;
        if (doc) {
            doc.open();
            doc.write('')//微软为doc.clear()有时会出bug
            doc.writeln(utils.formatString(""
, self.params.action));
            for (var key in self.params) 
                doc.writeln(utils.formatString("", key, self.params[key]));
            doc.writeln('<\/form><\/body><\/html>');
            doc.close();
            var form = doc.forms[0];
            if (form) {
                form.submit();
            }
        }
    };

    initFromGrid = function (grid) {
        var optiOns= grid.$element().datagrid('options');
        if (grid.treegrid)
            options.url = options.url || grid.treegrid('options').url;

        var titles = [[]], length = Math.max(options.frozenColumns.length, options.columns.length);
        for (var i = 0; i 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

大家基本都能看懂,不需要我再解释了。下载的原理是动态创建了一个iframe把参数写到input中提交到后台。


功能测试


通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

测试 html代码

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
Excel2003表格所有页
Excel2003表格指定页
Excel2003压缩zip
Excel2007/2010
PDF
Word
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

测试 js代码

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
        this.downloadClick1 = function(){
            com.exporter(self.grid).download("xls");
        };
        this.downloadClick2 = function(){
            com.exporter(self.grid).paging(2,3).download("xls"); 只做了5条数据,就3条一页吧,导出第2页
        };
        this.downloadClick3 = function(){
            com.exporter(self.grid).compress('zip').download("xls");
        };
        this.downloadClick4 = function(){
            com.exporter(self.grid).download("xlsx");
        };
        this.downloadClick5 = function(){
            com.exporter(self.grid).download("pdf");
        };
        this.downloadClick6 = function(){
            com.exporter(self.grid).download("doc");
        };
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

测试结果 
1 Excel2003表格所有页 com.exporter(self.grid).download("xls"); 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

2 Excel2003表格指定页  com.exporter(self.grid).page(2,3).download("xls"); 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等) 

3 Excel2003压缩zip com.exporter(self.grid).compress('zip').download("xls"); 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

4 Excel2007/2010  com.exporter(self.grid).download("xlsx"); 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

5 PDF导出 com.exporter(self.grid).download("pdf"); Gios这个组件出现中文会乱码,我想了很多办法都解决不了,没办法,可能要找一另一个pdf组件,先隐藏中文的字段截个图给大家看吧 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

6 Word导出 com.exporter(self.grid).download("doc"); 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

测试导出多行题头,比如这个页面是多行的 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

1 导出excel2003 多行题头 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

2 导出excel2007 多行题头 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

还有一些其它的功能我就不一一测试了,大家有兴趣可以自己再研究

在我们的材料管理的系统中导出一般只用几个选项,1 导出全部页excel2003 2 导出全部页excel2007/2010 3导出全部页word 这三个 
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)

所代码也很简单,代码如下:

通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
Excel2003
Excel2007
Word2003
通用的web系统数据导出功能设计实现(导出excel2003/2007 word pdf zip等)
this.downloadClick = function (vm, event) {
    com.exporter(self.grid).download($(event.currentTarget).attr("suffix"));
};

在我之前的博客中写共通的查询viewModel中有提到导出功能,但都只有上面的一句代码。估计大家看了这篇博客才能明白。


推荐阅读
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了如何将CIM_DateTime解析为.Net DateTime,并分享了解析过程中可能遇到的问题和解决方法。通过使用DateTime.ParseExact方法和适当的格式字符串,可以成功解析CIM_DateTime字符串。同时还提供了关于WMI和字符串格式的相关信息。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 站点用户可以在站点上注册,并且在注册期间可以提供名称.我希望此名称是有效名称,并且不包含任何HTML和其他时髦字符.strip_tags够吗?解决方法: ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
author-avatar
mbe5757086
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有
     
{0}