Как вывести таблицу Excel с изображениями из ASP.net - PullRequest
2 голосов
/ 26 октября 2010

Предположим, я пишу веб-приложение ASP.net.

Первоначальный дизайнер приложения использовал «PopChart» для отображения некоторых изображений в веб-приложении. На одной из страниц была кнопка «Экспорт в Excel». Когда кнопка нажата, содержимое страницы выводится в Excel, как в этом руководстве: http://aspalliance.com/articleViewer.aspx?aId=1&pId=.

По сути, он выводит HTML в файл XLS, а Excel интерпретирует его. Проблема в том, что мне нужно избавиться от PopChart. Я заменил его веб-элементом управления, который выводит файл PNG (который, кстати, может быть сохранен в объекте MemoryStream во время выполнения). PopChart ссылается на флэш-компонент, который запускается с публичного сервера; данные в «PopChart» встраиваются в HTML.

Однако, как только я начинаю использовать веб-элемент управления, который выводит PNG, все данные находятся в одном файле PNG. Я не вижу, что есть какой-либо способ вывести файл PNG с HTML. Я попытался встроить данные в img src=..., но Excel не будет их интерпретировать. Excel также не может загрузить файл PNG с сервера; сервер заблокирован, а Excel не имеет доступа к сеансу браузера.

Что я могу сделать?

Обновление: Я нашел следующий пример кода на форумах MSDN:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Validation;
using DocumentFormat.OpenXml.Drawing.Spreadsheet;

using System.IO;
using System.Drawing;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            string sFile = "ExcelOpenXmlWithImage.xlsx";
            if (File.Exists(sFile))
            {
                File.Delete(sFile);
            }
            BuildWorkbook(sFile);
        }

        private static void BuildWorkbook(string filename)
        {
            try
            {
                using (SpreadsheetDocument xl = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
                {
                    WorkbookPart wbp = xl.AddWorkbookPart();
                    WorksheetPart wsp = wbp.AddNewPart<WorksheetPart>();                                 
                    Workbook wb = new Workbook();
                    FileVersion fv = new FileVersion();
                    fv.ApplicationName = "Microsoft Office Excel";
                    Worksheet ws = new Worksheet();
                    SheetData sd = new SheetData();

                    //string sImagePath = "polymathlogo.png";
                    string sImagePath = @"c:\temp\chartImg.png";
                    DrawingsPart dp = wsp.AddNewPart<DrawingsPart>();
                    ImagePart imgp = dp.AddImagePart(ImagePartType.Png, wsp.GetIdOfPart(dp));
                    using (FileStream fs = new FileStream(sImagePath, FileMode.Open))
                    {
                        imgp.FeedData(fs);
                    }

                    NonVisualDrawingProperties nvdp = new NonVisualDrawingProperties();
                    nvdp.Id = 1025;
                    nvdp.Name = "Picture 1";
                    nvdp.Description = "polymathlogo";
                    DocumentFormat.OpenXml.Drawing.PictureLocks picLocks = new DocumentFormat.OpenXml.Drawing.PictureLocks();
                    picLocks.NoChangeAspect = true;
                    picLocks.NoChangeArrowheads = true;
                    NonVisualPictureDrawingProperties nvpdp = new NonVisualPictureDrawingProperties();
                    nvpdp.PictureLocks = picLocks;
                    NonVisualPictureProperties nvpp = new NonVisualPictureProperties();
                    nvpp.NonVisualDrawingProperties = nvdp;
                    nvpp.NonVisualPictureDrawingProperties = nvpdp;

                    DocumentFormat.OpenXml.Drawing.Stretch stretch = new DocumentFormat.OpenXml.Drawing.Stretch();
                    stretch.FillRectangle = new DocumentFormat.OpenXml.Drawing.FillRectangle();                    

                    BlipFill blipFill = new BlipFill();
                    DocumentFormat.OpenXml.Drawing.Blip blip = new DocumentFormat.OpenXml.Drawing.Blip();
                    blip.Embed = dp.GetIdOfPart(imgp);
                    blip.CompressionState = DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print;
                    blipFill.Blip = blip;
                    blipFill.SourceRectangle = new DocumentFormat.OpenXml.Drawing.SourceRectangle();
                    blipFill.Append(stretch);

                    DocumentFormat.OpenXml.Drawing.Transform2D t2d = new DocumentFormat.OpenXml.Drawing.Transform2D();
                    DocumentFormat.OpenXml.Drawing.Offset offset = new DocumentFormat.OpenXml.Drawing.Offset();
                    offset.X = 1000;
                    offset.Y = 1000;
                    t2d.Offset = offset;
                    Bitmap bm = new Bitmap(sImagePath);
                    //http://en.wikipedia.org/wiki/English_Metric_Unit#DrawingML
                    ///1209207/piksel-v-santimetr
                    //http://stackoverflow.com/questions/139655/how-to-convert-pixels-to-points-px-to-pt-in-net-c
                    DocumentFormat.OpenXml.Drawing.Extents extents = new DocumentFormat.OpenXml.Drawing.Extents();
                    extents.Cx = (long)bm.Width * (long)((float)914400 / bm.HorizontalResolution);
                    extents.Cy = (long)bm.Height * (long)((float)914400 / bm.VerticalResolution);
                    bm.Dispose();
                    t2d.Extents = extents;
                    ShapeProperties sp = new ShapeProperties();
                    sp.BlackWhiteMode = DocumentFormat.OpenXml.Drawing.BlackWhiteModeValues.Auto;
                    sp.Transform2D = t2d;
                    DocumentFormat.OpenXml.Drawing.PresetGeometry prstGeom = new DocumentFormat.OpenXml.Drawing.PresetGeometry();
                    prstGeom.Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle;
                    prstGeom.AdjustValueList = new DocumentFormat.OpenXml.Drawing.AdjustValueList();
                    sp.Append(prstGeom);
                    sp.Append(new DocumentFormat.OpenXml.Drawing.NoFill());

                    DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture picture = new DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture();
                    picture.NonVisualPictureProperties = nvpp;
                    picture.BlipFill = blipFill;
                    picture.ShapeProperties = sp;

                    Position pos = new Position();
                    pos.X =(Int64) 1000;
                    pos.Y =(Int64) 1000;
                    Extent ext = new Extent();
                    ext.Cx = extents.Cx;
                    ext.Cy = extents.Cy;
                    AbsoluteAnchor anchor = new AbsoluteAnchor();
                    anchor.Position = pos;
                    anchor.Extent = ext;
                    anchor.Append(picture);
                    anchor.Append(new ClientData());
                    WorksheetDrawing wsd = new WorksheetDrawing();
                    wsd.Append(anchor);
                    Drawing drawing = new Drawing();
                    drawing.Id = dp.GetIdOfPart(imgp);

                    wsd.Save(dp);                    

                    ws.Append(sd);
                    ws.Append(drawing);
                    wsp.Worksheet = ws;
                    wsp.Worksheet.Save();
                    Sheets sheets = new Sheets();
                    Sheet sheet = new Sheet();
                    sheet.Name = "Sheet1";
                    sheet.SheetId = 1;
                    sheet.Id = wbp.GetIdOfPart(wsp);
                    sheets.Append(sheet);
                    wb.Append(fv);
                    wb.Append(sheets);

                    xl.WorkbookPart.Workbook = wb;
                    xl.WorkbookPart.Workbook.Save();
                    xl.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Console.ReadLine();
            }
        }


    }
}

Этот код функционирует для создания новой электронной таблицы Excel со встроенным в нее изображением. Тем не менее, я не смог изменить этот код, чтобы поместить изображение, где я хочу, в электронную таблицу. (Да, я попытался изменить значение смещения.) Я также не смог успешно добавить текстовые или числовые данные в строки и столбцы.

Кто-нибудь здесь заставил это работать?

Ответы [ 2 ]

1 голос
/ 26 октября 2010

Взгляните на библиотеку NPOI , которая является отличной библиотекой для создания документов Excel (и других типов Office) в .Net.

Со своей библиотекой у них есть пример, демонстрирующий, как загружать изображения в Excel, который читает из файла. Поскольку POPChart может сохранять изображения в виде потока памяти, вы можете легко взять их пример и изменить его для чтения из потока памяти вместо файла. Остальная часть процесса генерации в Excel должна быть достаточно простой.

0 голосов
/ 29 декабря 2012

Чтобы изменить местоположение вашей картинки, вам нужно изменить rowId и columnId.Они действуют как индексы строк и столбцов, поэтому, если у вас есть ColumnId cId = new ColumnId ("2");и RowId rId = новый RowId ("1");Ваше изображение будет размещено в ячейке C2.Вам нужно будет сделать это дважды, один раз для начальных индексов и один раз для конечных индексов, если вы используете twoCellAnchor.

...