Моя задача сейчас состоит в том, чтобы пройти через некоторые книги в моем веб-приложении C# и объединить некоторые части каждой книги в одну новую книгу. Это требует от меня скопировать диапазоны ячеек с помощью SpreadsheetGear. В большинстве случаев это работает отлично, но копирование диапазона не копирует фигуры (изображения или диаграммы) внутри него.Копирование фигур (особенно диаграмм) с помощью SpreadsheetGear
Чтобы скопировать диаграммы, я решил просто определить диапазон ячеек, в пределах которого находится диаграмма, и превратить этот диапазон ячеек в изображение, которое я могу добавить в качестве рисунка на другой рабочий лист. Я тестировал это и имел частичный успех - некоторые форматы диаграмм, кажется, теряются при первоначальном открытии книги с помощью SpreadsheetGear. Кстати, при сохранении листа, содержащего такую диаграмму, исчезает еще большее форматирование.
Рабочие листы с диаграммами были сделаны с Excel 2013 года, и я использую SpreadsheetGear версии 7.1.1.120.
Вот изображения графиков, с которых я начинаю, и изображение, которое копируется из диапазона ячеек, содержащих график (еще одна странная вещь - обратите внимание, что форма в A2: A3 не позволяет скопировать ее диапазон и, действительно, не отображается в листе. Коллекция изображений).
https://i.imgsafe.org/dc2b7118c4.png
https://i.imgsafe.org/dc2bec6e8f.png
Вот некоторый минимальный код, который я использовал для получения приведенного выше примера. Я иду через все формы в листе и скопировать диапазон, содержащий форму, как изображение:
string exPath = System.Web.HttpContext.Current.Server.MapPath(@"~/App_Data");
string exFile = exPath + @"\examplechart.xlsx";
IWorkbook exBook = SpreadsheetGear.Factory.GetWorkbook(exFile, System.Globalization.CultureInfo.CurrentCulture);
IWorksheet inSheet = exBook.Worksheets["Sheet1"];
IWorksheet outSheet = exBook.Worksheets["Sheet2"];
SpreadsheetGear.Shapes.IShapes shapes = inSheet.Shapes;
foreach (SpreadsheetGear.Shapes.IShape shape in shapes)
{
IRange topLeft = shape.TopLeftCell;
IRange botRight = shape.BottomRightCell;
IRange imageRange = inSheet.Range[string.Format("{0}:{1}", topLeft.Address, botRight.Address)];
// Where to place the shape in terms of columns and rows
int destinationColumn = shape.TopLeftCell.Column;
int destinationRow = shape.TopLeftCell.Row;
// Copy column widths
imageRange.Copy(outSheet.Range[destinationRow, destinationColumn], SpreadsheetGear.PasteType.ColumnWidths, PasteOperation.None, false, false);
// Add the cell range within which the shape is, as a picture, in the correct place
double left = outSheet.WindowInfo.ColumnToPoints(destinationColumn);
double right = outSheet.WindowInfo.ColumnToPoints(destinationColumn + imageRange.ColumnCount);
double top = outSheet.WindowInfo.RowToPoints(destinationRow);
double bottom = outSheet.WindowInfo.RowToPoints(destinationRow + imageRange.RowCount);
SpreadsheetGear.Drawing.Image image = new SpreadsheetGear.Drawing.Image(imageRange);
Bitmap bitmap = image.GetBitmap();
ImageConverter converter = new ImageConverter();
byte[] byteArray = (byte[])converter.ConvertTo(bitmap, typeof(byte[]));
outSheet.Shapes.AddPicture(byteArray, left, top, right - left, bottom - top);
}
exBook.SaveAs(exPath + @"\examplechart-output.xlsx", FileFormat.OpenXMLWorkbook);
exBook.Close();
Я попытался превратить фигуры себя в образы, а не их диапазон ячеек, с теми же результатами. Это не похоже на то, что копирование фигур и диаграмм очень распространено в SpreadsheetGear, поэтому, возможно, поэтому я не слышал об этих типах проблем (или, может быть, я просто использую слишком старую версию SpreadsheetGear?) ,
Если кто знает, почему диаграмма выглядит так странно при открытии SpreadsheetGear, это главное, что я пытаюсь выяснить. Но если кто-то знает более прямой способ копирования фигур (включая диаграммы) с одного листа на другой, это также может решить мою проблему. (Возможно, вопрос в бонусе: почему форма при A2: A3 отсутствует даже там, когда лист открыт с помощью SpreadsheetGear?)