.net导出图片到Excel

首先:Model类

public class InfoVM
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { set; get; }

        /// <summary>
        /// 类别
        /// </summary>
        public string Category { set; get; }

        /// <summary>
        /// 内容信息
        /// </summary>
        public string Description { set; get; }

        /// <summary>
        /// 是否发布
        /// </summary>
        public bool IsRelease { set; get; }

        /// <summary>
        /// 文件路径
        /// </summary>
        public string FilePath { set; get; }

        /// <summary>
        /// 图片字节
        /// </summary>
        public byte[] ImageBytes { set; get; }
    }

然后构造要导入的Excel信息:

/// <summary>
        /// 导出Excel
        /// </summary>
        /// <returns></returns>
        public JsonResult Export()
        {
            string rooturl = Request.Url.GetLeftPart(UriPartial.Authority);
            List<InfoVM> list = new List<InfoVM>();
            Random ram = new Random();
            for (int i = 1; i < 100; i++)
            {
                InfoVM vm = new InfoVM();
                vm.Title = "信息的标题" + i;
                vm.Category = "大事记";
                vm.IsRelease = i % 2 == 0;
                int xh = ram.Next(1,3);
                vm.FilePath = string.Format("/Files/0{0}.jpg", xh);
                string fullpath = vm.FilePath;
                if (!fullpath.StartsWith("http") || fullpath.StartsWith("/"))
                {
                    fullpath = string.Format("{0}{1}", rooturl,vm.FilePath);
                }
                vm.ImageBytes = NetHelper.GetImgBytes(fullpath);
                list.Add(vm);
            }
            ResultModel rm = new ResultModel();
            try
            {
                string fileExt = ".xlsx";
                string fileName = string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now) + fileExt;
                string fullPath = HttpRuntime.AppDomainAppPath+string.Format("Files\\{0}",fileName);
                DataTable dt = ExcelHelper.GetTabFromList<InfoVM>(list);
                string errmsg = string.Empty;
                bool issuc = ExcelHelper.ReadDataTabToExcel(fullPath,dt, ref errmsg,"大事记", "大事记", fileExt);
                if (issuc)
                {
                    rm.Err = 0;
                    rm.Msg = "生成成功";
                    rm.Data = string.Format("/Files/{0}", fileName);
                }
                else
                {
                    rm.Err = 1;
                    rm.Msg = errmsg;
                }
            }
            catch(Exception ex)
            {
                rm.Err = 1;
                rm.Msg = ex.Message;
            }
            return Json(rm,JsonRequestBehavior.AllowGet);
        }

Excel帮助类如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Reflection;

namespace TestUpfile
{
    public class ExcelHelper
    {
        /// <summary>
        /// 将Excel文件转成dataset(针对有多个工作表、并且多个工作表结构一致)
        /// </summary>
        /// <param name="excelFilePath">Excel文件</param>
        /// <param name="headerRowIndex">表头行</param>
        /// <param name="fTitle">返回文件标题</param>
        /// <returns></returns>
        public static DataTable GeneralDataSetFromExcel(string excelFilePath, int headerRowIndex, ref string fTitle, string fileext = ".xlsx")
        {
            DataTable dt = new DataTable();
            dt = GeneralDataSetFromExcel(System.IO.File.OpenRead(excelFilePath), headerRowIndex, ref fTitle,fileext);
            return dt;
        }

        /// <summary>
        /// 将Excel文件转成dataset(针对有多个工作表、并且多个工作表结构一致)
        /// </summary>
        /// <param name="stream">Excel文件流</param>
        /// <param name="headerRowIndex">表头行</param>
        /// <param name="fTitle">返回文件标题</param>
        /// <returns></returns>
        public static DataTable GeneralDataSetFromExcel(Stream stream, int headerRowIndex, ref string fTitle, string fileext= ".xlsx")
        {
            DataTable dt = new DataTable();
            IWorkbook workbook = null;
            if (fileext == ".xlsx")
            {
                workbook = new XSSFWorkbook(stream);
            }
            else
            {
                workbook = new HSSFWorkbook(stream);
            }
            //XSSFWorkbook workbook = new XSSFWorkbook(stream);
            int sheetIndex = 0;
            ISheet sheet = workbook.GetSheetAt(sheetIndex);
            //先去掉表头标题行
            IRow headerRow = sheet.GetRow(headerRowIndex);
            if (headerRow == null)
            {
                while (headerRow == null)
                {
                    headerRowIndex++;
                    headerRow = sheet.GetRow(headerRowIndex);
                    if (headerRowIndex > 5) break;
                }
            }
            fTitle = headerRow.GetCell(0).StringCellValue;

            //本次的Excel是双表头
            headerRowIndex += 1;//加1行,跳过表头
            IRow secondeRow = sheet.GetRow(headerRowIndex);
            headerRowIndex += 1;//加1行,跳过表头
            IRow thirdRow = sheet.GetRow(headerRowIndex);
            int cellCount = thirdRow.LastCellNum;
            int secondCellIndex = 0;
            int thirdCellIndex = 0;
            for (int i = secondeRow.FirstCellNum; i < cellCount; i++)
            {
                ICell cell = secondeRow.GetCell(i);
                if (cell == null || cell.StringCellValue == "")
                {
                    //第二行为空,则看第三行是否也为空,如果两行都为空,则跳过
                    ICell tcell = thirdRow.GetCell(thirdCellIndex);
                    if (tcell == null || tcell.StringCellValue == "")
                    {
                        continue;
                    }
                    else
                    {
                        DataColumn column = new DataColumn(tcell.StringCellValue);
                        dt.Columns.Add(column);
                        secondCellIndex++;
                        thirdCellIndex++;
                    }
                }
                else
                {
                    string cellValue = cell.StringCellValue;
                    if (cellValue == "意见提出人信息" || cellValue == "意见对应情况")
                    {
                        //这是合并的,意见提出人信息下面有两列,意见对应情况下面有四列
                        if (cellValue == "意见提出人信息")
                        {
                            //下面有两列,切换到下一行的单元格
                            for (int j = 0; j < 2; j++)
                            {
                                ICell tcell = thirdRow.GetCell(thirdCellIndex);
                                if (tcell.StringCellValue != "")
                                {
                                    DataColumn column = new DataColumn(tcell.StringCellValue);
                                    dt.Columns.Add(column);
                                }
                                else
                                {
                                    //补齐列
                                    DataColumn column = new DataColumn("Emp" + Guid.NewGuid().ToString().Replace("-", ""));
                                    dt.Columns.Add(column);
                                }
                                thirdCellIndex++;
                            }
                            secondCellIndex++;
                        }
                        if (cellValue == "意见对应情况")
                        {
                            //下面有四列,切换到下一行的单元格
                            for (int j = 0; j < 3; j++)
                            {
                                ICell tcell = thirdRow.GetCell(thirdCellIndex);
                                if (tcell.StringCellValue != "")
                                {
                                    DataColumn column = new DataColumn(tcell.StringCellValue);
                                    dt.Columns.Add(column);
                                }
                                else
                                {
                                    //补齐列
                                    DataColumn column = new DataColumn("Emp" + Guid.NewGuid().ToString().Replace("-", ""));
                                    dt.Columns.Add(column);
                                }
                                thirdCellIndex++;
                            }
                            secondCellIndex++;
                        }
                    }
                    else
                    {
                        if (cell.StringCellValue != "")
                        {
                            DataColumn column = new DataColumn(cell.StringCellValue);
                            dt.Columns.Add(column);
                        }
                        secondCellIndex++;
                        thirdCellIndex++;
                    }
                }


            }
            for (int i = (headerRowIndex + 1); i <= sheet.LastRowNum; i++)
            {
                IRow row = sheet.GetRow(i);
                int rownum = row.Cells.Count;
                int max = 10;
                bool isnull = false;
                if (max > rownum) max = rownum;//检查前三列是否有数据,如果前三都没有,则不再向后读取
                int cnt = 0;
                for (int k = 0; k < max; k++)
                {
                    if (row == null) break;
                    ICell cell = row.GetCell(k);
                    if (cell == null) break;
                    if (cell.CellType == CellType.String)
                    {
                        if (cell.StringCellValue.Trim() == "")
                        {
                            cnt++;
                            if (cnt >= 3)
                            {
                                // 如果遇到第一个空行,则不再继续向后读取
                                isnull = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                if (isnull)
                {
                    continue;
                }
                DataRow dataRow = dt.NewRow();
                for (int j = row.FirstCellNum; j < cellCount; j++)
                {
                    dataRow[j] = row.GetCell(j);
                }
                dt.Rows.Add(dataRow);
            }
            sheet = null;
            workbook = null;
            return dt;
        }


        /// <summary>
        /// 将一个datatable写入一个Excel文件,按人导出门禁
        /// </summary>
        /// <param name="tab"></param>
        /// <returns></returns>
        public static bool ReadDataTabToExcel(string savePath,DataTable tab,ref string errmsg, string sheetname = null, string tabtitle = null,string fileExt=".xlsx")
        {
            try
            {
                Stream stream = new MemoryStream();
                IWorkbook workbook = null;
                if (fileExt.ToLower() == ".xlsx")
                {
                    workbook = new XSSFWorkbook();
                }
                else
                {
                    workbook = new HSSFWorkbook();
                }

                int totalcount = tab.Rows.Count;
                int max = 65510;//设置每个sheet最多存储数量
                int totalsheet = 1;
                if (totalcount % max == 0)
                {
                    totalsheet = totalcount / max;
                }
                else
                {
                    totalsheet = totalcount / max + 1;
                }

                ICellStyle headstyle = workbook.CreateCellStyle();
                headstyle.FillBackgroundColor = HSSFColor.Teal.Index;
                headstyle.FillPattern = FillPattern.SolidForeground;
                headstyle.FillForegroundColor = HSSFColor.Grey25Percent.Index;
                headstyle.Alignment = HorizontalAlignment.Center;
                IFont font12 = workbook.CreateFont();
                font12.FontName = "微软雅黑";
                font12.Boldweight = 15;
                font12.FontHeightInPoints = 12;
                headstyle.SetFont(font12);
                headstyle.BorderBottom = BorderStyle.Hair;

                //带背景色,并且文字居中
                ICellStyle huibgstyle = workbook.CreateCellStyle();
                huibgstyle.FillBackgroundColor = HSSFColor.SeaGreen.Index;
                huibgstyle.FillPattern = FillPattern.SolidForeground;
                huibgstyle.FillForegroundColor = HSSFColor.SeaGreen.Index;
                huibgstyle.Alignment = HorizontalAlignment.Center;
                huibgstyle.VerticalAlignment = VerticalAlignment.Top;
                huibgstyle.BorderTop = BorderStyle.Thin;
                huibgstyle.BorderRight = BorderStyle.Thin;
                huibgstyle.BorderBottom = BorderStyle.Thin;
                huibgstyle.BorderLeft = BorderStyle.Thin;

                //普通的行,只是文字居中
                ICellStyle norstyle = workbook.CreateCellStyle();
                norstyle.Alignment = HorizontalAlignment.Center;
                norstyle.VerticalAlignment = VerticalAlignment.Top;
                norstyle.BorderTop = BorderStyle.Thin;
                norstyle.BorderRight = BorderStyle.Thin;
                norstyle.BorderBottom = BorderStyle.Thin;
                norstyle.BorderLeft = BorderStyle.Thin;

                for (int shct = 0; shct < totalsheet; shct++)
                {
                    ISheet sheet = null;
                    if (string.IsNullOrEmpty(sheetname))
                    {
                        sheet = workbook.CreateSheet();
                    }
                    else
                    {
                        sheet = workbook.CreateSheet(sheetname + (shct + 1));
                    }
                    //CellRangeAddress()该方法的参数次序是:开始行号,结束行号,开始列号,结束列号。

                    sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, tab.Columns.Count-1));
                    IRow frow = sheet.CreateRow(0);
                    frow.Height = 30 * 20;
                    ICellStyle fstyle = workbook.CreateCellStyle();
                    IFont font14 = workbook.CreateFont();
                    font14.FontName = "微软雅黑";
                    font14.FontHeightInPoints = 14;
                    font14.Color = HSSFColor.Blue.Index;
                    font14.Boldweight = short.MaxValue;
                    fstyle.Alignment = HorizontalAlignment.Center;
                    fstyle.VerticalAlignment = VerticalAlignment.Center;
                    fstyle.SetFont(font14);
                    ICell fcell = frow.CreateCell(0);
                    fcell.SetCellValue(tabtitle);
                    fcell.CellStyle = fstyle;


                    IRow headerRow = sheet.CreateRow(1);


                    //第一列是序号,第二列是门禁名称,按名称来设置背景色
                    int rownum = 0;
                    string prevmj = "";
                    foreach (DataColumn column in tab.Columns)
                    {
                        string colName = column.ColumnName;
                        string cnName = colName;
                        switch (colName)
                        {
                            case "Title":
                                {
                                    cnName = "标题";
                                    break;
                                }
                            case "Category":
                                {
                                    cnName = "类别";
                                    break;
                                }
                            case "Description":
                                {
                                    cnName = "内容";
                                    break;
                                }
                            case "IsRelease":
                                {
                                    cnName = "是否发布";
                                    break;
                                }
                            case "FilePath":
                                {
                                    cnName = "文件路径";
                                    break;
                                }
                            case "ImageBytes":
                                {
                                    cnName = "图片";
                                    break;
                                }
                        }
                        headerRow.CreateCell(column.Ordinal).SetCellValue(cnName);
                        headerRow.GetCell(column.Ordinal).CellStyle = headstyle;
                        //列宽每个像素1/256
                        if (column.ColumnName == "Title")
                        {
                            sheet.SetColumnWidth(column.Ordinal, 50 * 256);
                        }
                        if (column.ColumnName == "Description")
                        {
                            sheet.SetColumnWidth(column.Ordinal, 100 * 256);
                        }
                        if (column.ColumnName == "FilePath")
                        {
                            sheet.SetColumnWidth(column.Ordinal, 50 * 256);
                        }
                        if(column.ColumnName== "ImageBytes")
                        {
                            sheet.SetColumnWidth(column.Ordinal, 60 * 256);
                        }
                    }
                    int rowIndex = 2;
                    int curmin = shct * max;
                    int curmax = shct * max + max;
                    if (curmax > totalcount) curmax = totalcount;
                    for (int ct = curmin; ct < curmax; ct++)
                    {
                        DataRow row = tab.Rows[ct];
                        //string curmj = row["卡号"].ToString();
                        //if (string.IsNullOrEmpty(prevmj))
                        //{
                        //    prevmj = curmj;
                        //}
                        //if (curmj != prevmj)
                        //{
                        //    prevmj = curmj;
                        //    rownum++;
                        //}
                        ICellStyle style = norstyle;
                        if (rownum % 2 != 0)
                        {
                            style = huibgstyle;
                        }
                        IRow datarow = sheet.CreateRow(rowIndex);
                        datarow.Height = 100 * 20;//设置行高,Excel行高的每个像素点是1/20
                        foreach (DataColumn col in tab.Columns)
                        {
                            if(col.ColumnName== "ImageBytes")
                            {
                                byte[] bytes = (byte[])row[col.ColumnName];
                                if (bytes != null)
                                {
                                    int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG);
                                    IDrawing patriarch = sheet.CreateDrawingPatriarch();
                                    IClientAnchor anchor = patriarch.CreateAnchor(70, 10, 0, 0, col.Ordinal, rowIndex, col.Ordinal+1, rowIndex + 1);
                                    IPicture pict = patriarch.CreatePicture(anchor, pictureIdx);
                                }
                            }
                            else
                            {
                                string content = row[col.ColumnName].ToString();
                                datarow.CreateCell(col.Ordinal).SetCellValue(content);
                                datarow.GetCell(col.Ordinal).CellStyle = style;
                            }
                        }
                        rowIndex++;
                    }
                }
                using(FileStream fs=new FileStream(savePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    workbook.Write(fs);
                }
            }
            catch(Exception ex)
            {
                errmsg = ex.Message;
                return false;
            }
            return true;
        }

        /// <summary>
        /// 将list转成datatable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable GetTabFromList<T>(IList<T> list)
        {
            if (list == null || list.Count == 0) return null;
            DataTable dt = new DataTable();
            Type type = typeof(T);
            PropertyInfo[] pinfos = type.GetProperties();
            foreach (var pi in pinfos)
            {
                Type mytp = pi.PropertyType;
                DataColumn dc = new DataColumn(pi.Name, mytp);
                dt.Columns.Add(dc);
            }
            foreach (var t in list)
            {
                DataRow dr = dt.NewRow();
                foreach (var pi in pinfos)
                {
                    object ov = pi.GetValue(t, null);
                    dr[pi.Name] = ov;
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

        /// <summary>
        /// 返回一个json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetJsonMsg(object obj)
        {
            IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
            timeConverter.DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
            return JsonConvert.SerializeObject(obj, Formatting.Indented, timeConverter);
        }

        public static byte[] CopyStream(Stream stream)
        {
            int len = 1024;
            byte[] bytes = new byte[len];
            MemoryStream ms = new MemoryStream();
            int count = 0;
            while ((count = stream.Read(bytes, 0, len)) > 0)
            {
                ms.Write(bytes, 0, count);
            }
            stream.Seek(0, SeekOrigin.Begin);
            return ms.ToArray();
        }
    }
}

参数的解析: HSSFClientAnchor(int dx1,int dy1,int dx2,int dy2,int col1,int row1,int col2,int row2)
dx1:图片左边相对excel格的位置(x偏移) 范围值为:0~1023;即输100 偏移的位置大概是相对于整个单元格的宽度的100除以1023大概是10分之一
dy1:图片上方相对excel格的位置(y偏移) 范围值为:0~256 原理同上。
dx2:图片右边相对excel格的位置(x偏移) 范围值为:0~1023; 原理同上。
dy2:图片下方相对excel格的位置(y偏移) 范围值为:0~256 原理同上。
col1和row1 :图片左上角的位置,以excel单元格为参考,比喻这两个值为(1,1),那么图片左上角的位置就是excel表(1,1)单元格的右下角的点(A,1)右下角的点。
col2和row2:图片右下角的位置,以excel单元格为参考,比喻这两个值为(2,2),那么图片右下角的位置就是excel表(2,2)单元格的右下角的点(B,2)右下角的点。

导出的结果如图:

猜你喜欢

转载自www.cnblogs.com/ymworkroom/p/11851509.html