在 Excel 单元格中导出多个图像时遇到问题。我在页面中单击一个简单的按钮来做到这一点。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using A = DocumentFormat.OpenXml.Drawing;
using Xdr = DocumentFormat.OpenXml.Drawing.Spreadsheet;
using A14 = DocumentFormat.OpenXml.Office2010.Drawing;
using System.IO;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace OpenXMLExport
{
public partial class _Default : System.Web.UI.Page
{
public static string ImageFile = HttpContext.Current.Server.MapPath(@"~\Data\Sunset.jpg");
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
DataTable table = GetTable();
DataSet ds = new DataSet();
ds.Tables.Add(table);
ExportDataSet(ds, HttpContext.Current.Server.MapPath(@"~\Data\ImageExport.xlsx"));
}
/// <summary>
/// This example method generates a DataTable.
/// </summary>
static DataTable GetTable()
{
//
// Here we create a DataTable with four columns.
//
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Image", typeof(string));
//
// Here we add five DataRows.
//
table.Rows.Add(25, "Indocin", "David");
table.Rows.Add(50, "Enebrel", "Sam");
//table.Rows.Add(10, "Hydralazine", "Christoff");
return table;
}
private void ExportDataSet(DataSet ds, string destination)
{
using (var workbook = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Create(
destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
foreach (System.Data.DataTable table in ds.Tables)
{
var sheetPart = workbook.WorkbookPart.AddNewPart<DocumentFormat.OpenXml.Packaging.WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
//DocumentFormat.OpenXml.Spreadsheet.SheetFormatProperties sheetFormatProperties2 = new DocumentFormat.OpenXml.Spreadsheet.SheetFormatProperties() { DefaultRowHeight = 15D };
//sheetPart.Worksheet.Append(sheetFormatProperties2);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets =
workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
{
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet()
{ Id = relationshipId, SheetId = sheetId, Name = table.TableName };
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (System.Data.DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (System.Data.DataRow dsrow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
{
if (col.ToString() != "Image")
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
}
else
{
DocumentFormat.OpenXml.Packaging.WorksheetPart sheet1 = GetSheetByName(workbookPart, "sheet");
InsertImage(sheet1, 1, 3, 3, 6, new FileStream(ImageFile, FileMode.Open,FileAccess.ReadWrite));
workbook.WorkbookPart.Workbook.Save();
}
}
sheetData.AppendChild(newRow);
}
// Close the document handle.
workbook.Close();
DownloadFile(HttpContext.Current.Server.MapPath(@"~\Data\ImageExport.xlsx"));
//System.Diagnostics.Process.Start(HttpContext.Current.Server.MapPath(@"\ImageExport.xlsx"));
}
}
}
public static void DownloadFile(string filePath)
{
string path = filePath;// HttpContext.Current.Server.MapPath(filePath);
System.IO.FileInfo file = new System.IO.FileInfo(path);
if (file.Exists)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.WriteFile(file.FullName);
HttpContext.Current.Response.End();
}
}
/// <summary>
/// Returns the WorksheetPart for the specified sheet name
/// </summary>
/// <param name="workbookpart">The WorkbookPart</param>
/// <param name="sheetName">The name of the worksheet</param>
/// <returns>Returns the WorksheetPart for the specified sheet name</returns>
private static DocumentFormat.OpenXml.Packaging.WorksheetPart GetSheetByName(DocumentFormat.OpenXml.Packaging.WorkbookPart workbookpart, string sheetName)
{
foreach (DocumentFormat.OpenXml.Packaging.WorksheetPart sheetPart in workbookpart.WorksheetParts)
{
string uri = sheetPart.Uri.ToString();
if (uri.EndsWith(sheetName + ".xml"))
return sheetPart;
}
return null;
}
/// <summary>
/// Inserts the image at the specified location
/// </summary>
/// <param name="sheet1">The WorksheetPart where image to be inserted</param>
/// <param name="startRowIndex">The starting Row Index</param>
/// <param name="startColumnIndex">The starting column index</param>
/// <param name="endRowIndex">The ending row index</param>
/// <param name="endColumnIndex">The ending column index</param>
/// <param name="imageStream">Stream which contains the image data</param>
private static void InsertImage(DocumentFormat.OpenXml.Packaging.WorksheetPart sheet1,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex, Stream imageStream)
{
//Inserting a drawing element in worksheet
//Make sure that the relationship id is same for drawing element in worksheet and its relationship part
int drawingPartId = GetNextRelationShipID(sheet1);
DocumentFormat.OpenXml.Spreadsheet.Drawing drawing1 = new DocumentFormat.OpenXml.Spreadsheet.Drawing()
{ Id = "rId" + drawingPartId.ToString() };
//Check whether the WorksheetPart contains VmlDrawingParts (LegacyDrawing element)
if (sheet1.VmlDrawingParts == null)
{
//if there is no VMLDrawing part (LegacyDrawing element) exists, just append the drawing part to the sheet
sheet1.Worksheet.Append(drawing1);
}
else
{
//if VmlDrawingPart (LegacyDrawing element) exists, then find the index of legacy drawing in the sheet and inserts the new drawing element before VMLDrawing part
int legacyDrawingIndex = GetIndexofLegacyDrawing(sheet1);
if (legacyDrawingIndex != -1)
sheet1.Worksheet.InsertAt<DocumentFormat.OpenXml.OpenXmlElement>(drawing1, legacyDrawingIndex);
else
sheet1.Worksheet.Append(drawing1);
}
//Adding the drawings.xml part
DocumentFormat.OpenXml.Packaging.DrawingsPart drawingsPart1
= sheet1.AddNewPart<DocumentFormat.OpenXml.Packaging.DrawingsPart>("rId" + drawingPartId.ToString());
GenerateDrawingsPart1Content(drawingsPart1, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex);
//Adding the image
DocumentFormat.OpenXml.Packaging.ImagePart imagePart1 = drawingsPart1.AddNewPart<DocumentFormat.OpenXml.Packaging.ImagePart>("image/jpeg", "rId1");
imagePart1.FeedData(imageStream);
}
// Generates content of drawingsPart1.
private static void GenerateDrawingsPart1Content(DocumentFormat.OpenXml.Packaging.DrawingsPart drawingsPart1, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex)
{
Xdr.WorksheetDrawing worksheetDrawing1 = new Xdr.WorksheetDrawing();
worksheetDrawing1.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
worksheetDrawing1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
Xdr.TwoCellAnchor twoCellAnchor1 = new Xdr.TwoCellAnchor() { EditAs = Xdr.EditAsValues.OneCell };
Xdr.FromMarker fromMarker1 = new Xdr.FromMarker();
Xdr.ColumnId columnId1 = new Xdr.ColumnId();
columnId1.Text = startColumnIndex.ToString();
Xdr.ColumnOffset columnOffset1 = new Xdr.ColumnOffset();
columnOffset1.Text = "38100";
Xdr.RowId rowId1 = new Xdr.RowId();
rowId1.Text = startRowIndex.ToString();
Xdr.RowOffset rowOffset1 = new Xdr.RowOffset();
rowOffset1.Text = "0";
fromMarker1.Append(columnId1);
fromMarker1.Append(columnOffset1);
fromMarker1.Append(rowId1);
fromMarker1.Append(rowOffset1);
Xdr.ToMarker toMarker1 = new Xdr.ToMarker();
Xdr.ColumnId columnId2 = new Xdr.ColumnId();
columnId2.Text = endColumnIndex.ToString();
Xdr.ColumnOffset columnOffset2 = new Xdr.ColumnOffset();
columnOffset2.Text = "542925";
Xdr.RowId rowId2 = new Xdr.RowId();
rowId2.Text = endRowIndex.ToString();
Xdr.RowOffset rowOffset2 = new Xdr.RowOffset();
rowOffset2.Text = "161925";
toMarker1.Append(columnId2);
toMarker1.Append(columnOffset2);
toMarker1.Append(rowId2);
toMarker1.Append(rowOffset2);
Xdr.Picture picture1 = new Xdr.Picture();
Xdr.NonVisualPictureProperties nonVisualPictureProperties1 = new Xdr.NonVisualPictureProperties();
Xdr.NonVisualDrawingProperties nonVisualDrawingProperties1 = new Xdr.NonVisualDrawingProperties() { Id = (DocumentFormat.OpenXml.UInt32Value)2U, Name = "Picture 1" };
//DocumentFormat.OpenXml.Spreadsheet.SheetFormatProperties sheetFormatProperties3
// = new DocumentFormat.OpenXml.Spreadsheet.SheetFormatProperties() { DefaultRowHeight = 15D ,DefaultColumnWidth = 25D};
Xdr.NonVisualPictureDrawingProperties nonVisualPictureDrawingProperties1 = new Xdr.NonVisualPictureDrawingProperties();
A.PictureLocks pictureLocks1 = new A.PictureLocks() { NoChangeAspect = true };
nonVisualPictureDrawingProperties1.Append(pictureLocks1);
nonVisualPictureProperties1.Append(nonVisualDrawingProperties1);
nonVisualPictureProperties1.Append(nonVisualPictureDrawingProperties1);
Xdr.BlipFill blipFill1 = new Xdr.BlipFill();
A.Blip blip1 = new A.Blip() { Embed = "rId1", CompressionState = A.BlipCompressionValues.Print };
blip1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
A.BlipExtensionList blipExtensionList1 = new A.BlipExtensionList();
A.BlipExtension blipExtension1 = new A.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" };
A14.UseLocalDpi useLocalDpi1 = new A14.UseLocalDpi() { Val = false };
useLocalDpi1.AddNamespaceDeclaration("a14", "http://schemas.microsoft.com/office/drawing/2010/main");
blipExtension1.Append(useLocalDpi1);
blipExtensionList1.Append(blipExtension1);
blip1.Append(blipExtensionList1);
A.Stretch stretch1 = new A.Stretch();
A.FillRectangle fillRectangle1 = new A.FillRectangle();
stretch1.Append(fillRectangle1);
blipFill1.Append(blip1);
blipFill1.Append(stretch1);
Xdr.ShapeProperties shapeProperties1 = new Xdr.ShapeProperties();
A.Transform2D transform2D1 = new A.Transform2D();
A.Offset offset1 = new A.Offset() { X = 1257300L, Y = 762000L };
A.Extents extents1 = new A.Extents() { Cx = 2943225L, Cy = 2257425L };
transform2D1.Append(offset1);
transform2D1.Append(extents1);
A.PresetGeometry presetGeometry1 = new A.PresetGeometry() { Preset = A.ShapeTypeValues.Rectangle };
A.AdjustValueList adjustValueList1 = new A.AdjustValueList();
presetGeometry1.Append(adjustValueList1);
shapeProperties1.Append(transform2D1);
shapeProperties1.Append(presetGeometry1);
picture1.Append(nonVisualPictureProperties1);
picture1.Append(blipFill1);
picture1.Append(shapeProperties1);
Xdr.ClientData clientData1 = new Xdr.ClientData();
//CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U };
//CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U };
//cellStyleFormats1.Append(cellFormat1);
//CellFormats cellFormats1 = new CellFormats() { Count = (UInt32Value)4U };
//CellFormat cellFormat2 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U };
//CellFormat cellFormat3 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)2U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
//CellFormat cellFormat4 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)3U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
//CellFormat cellFormat5 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)4U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
//cellFormats1.Append(cellFormat2);
//cellFormats1.Append(cellFormat3);
//cellFormats1.Append(cellFormat4);
//cellFormats1.Append(cellFormat5);
//CellStyles cellStyles1 = new CellStyles() { Count = (UInt32Value)1U };
//CellStyle cellStyle1 = new CellStyle() { Name = "Normal", FormatId = (UInt32Value)0U, BuiltinId = (UInt32Value)0U };
//cellStyles1.Append(cellStyle1);
//twoCellAnchor1.Append(cellStyles1);
//twoCellAnchor1.Append(cellFormats1);
twoCellAnchor1.Append(fromMarker1);
twoCellAnchor1.Append(toMarker1);
twoCellAnchor1.Append(picture1);
twoCellAnchor1.Append(clientData1);
//twoCellAnchor1.Append(sheetFormatProperties3);
worksheetDrawing1.Append(twoCellAnchor1);
drawingsPart1.WorksheetDrawing = worksheetDrawing1;
}
/// <summary>
/// Get the index of legacy drawing element in the specified WorksheetPart
/// </summary>
/// <param name="sheet1">The worksheetPart</param>
/// <returns>Index of legacy drawing</returns>
private static int GetIndexofLegacyDrawing(DocumentFormat.OpenXml.Packaging.WorksheetPart sheet1)
{
for (int i = 0; i < sheet1.Worksheet.ChildElements.Count; i++)
{
DocumentFormat.OpenXml.OpenXmlElement element = sheet1.Worksheet.ChildElements[i];
if (element is DocumentFormat.OpenXml.Spreadsheet.LegacyDrawing)
return i;
}
return -1;
}
/// <summary>
/// Returns the next relationship id for the specified WorksheetPart
/// </summary>
/// <param name="sheet1">The worksheetPart</param>
/// <returns>Returns the next relationship id </returns>
private static int GetNextRelationShipID(DocumentFormat.OpenXml.Packaging.WorksheetPart sheet1)
{
int nextId = 0;
List<int> ids = new List<int>();
foreach (DocumentFormat.OpenXml.Packaging.IdPartPair part in sheet1.Parts)
{
ids.Add(int.Parse(part.RelationshipId.Replace("rId", string.Empty)));
}
if (ids.Count > 0)
nextId = ids.Max() + 1;
else
nextId = 1;
return nextId;
}
}
}
如果我尝试用一行导出一个表,它的工作正常。但是我遇到了多行的问题
DocumentFormat.OpenXml.Packaging.DrawingsPart drawingsPart1
= sheet1.AddNewPart<DocumentFormat.OpenXml.Packaging.DrawingsPart>("rId" + drawingPartId.ToString());
在添加第二行的绘图部分时,我收到错误“此父级只允许该类型的一个实例”。
但在我的情况下仍然无法解决......我只需要使用 OpenXMl