Hinzufügen eines Bildes zu excel mithilfe von openxml sdk
Ich versuche ein Bild hinzufügen, um excel-Dokument, das erzeugt wurde, closedxml mithilfe von openxml, nachdem die Tabelle erzeugt wurde (da closedxml keine Möglichkeit hat, Bilder einfügen, derzeit).
Kann ich generieren, die excel-Datei korrekt angezeigt und es öffnet sich Ordnung aber wenn ich versuchen Sie, das Bild und versuchen Sie, öffnen Sie Sie in excel gibt Es einen Fehler.
Habe ich eine kleine Konsolenanwendung und den Fehler gefunden zu werden
Error 1
Description: The element has unexpected child element 'http://schemas.openxmlfor
mats.org/spreadsheetml/2006/main:drawing'.
Path: /x:worksheet[1]
Part: /xl/worksheets/sheet.xml
-------------------------------------------
Arbeitsblatt sieht wie folgt aus:
<?xml version="1.0" encoding="utf-8"?>
<x:worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheetPr>
<x:outlinePr summaryBelow="1" summaryRight="1" />
</x:sheetPr>
<x:dimension ref="A1:M4" />
<x:sheetViews>
<x:sheetView tabSelected="0" workbookViewId="0" />
</x:sheetViews>
<x:sheetFormatPr defaultRowHeight="15" />
<x:cols>
...
</x:cols>
<x:sheetData>
...
</x:sheetData>
<x:printOptions horizontalCentered="0" verticalCentered="0" headings="0" gridLines="0" />
<x:pageMargins left="0.75" right="0.75" top="0.75" bottom="0.5" header="0.5" footer="0.75" />
<x:pageSetup paperSize="1" scale="100" pageOrder="downThenOver" orientation="default" blackAndWhite="0" draft="0" cellComments="none" errors="displayed" />
<x:headerFooter />
<x:tableParts count="0" />
<x:drawing r:id="R701e4d0efd7143ee" />
</x:worksheet>
Unter der
Abschnitt scheint zu erlauben, die Datei zu validieren richtig.
Ich habe auch versucht, erstellen Sie ein leeres excel-Dokument manuell hinzufügen und ein Bild und es sieht sehr ähnlich aus:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<dimension ref="A1"/>
<sheetViews>
<sheetView tabSelected="1" workbookViewId="0">
<selection activeCell="D14" sqref="D14"/>
</sheetView>
</sheetViews>
<sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
<sheetData/>
<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
<drawing r:id="rId1"/>
</worksheet>
Eine Sache, die ich bemerkt ist, dass Sie nicht haben, ein namespace (x) wie generiert man tut, aber ich weiß nicht, ob das ein problem verursacht oder nicht.
Kann jemand sehen, was ich bin fehlt?
Den code im mit einfügen das Bild ist wie folgt:
public static void InsertImage(this Worksheet ws, long x, long y, long? width, long? height, string sImagePath)
{
try
{
var wsp = ws.WorksheetPart;
var dp = default(DrawingsPart);
var imgp = default(ImagePart);
var wsd = default(WorksheetDrawing);
var ipt = default(ImagePartType);
switch (sImagePath.Substring(sImagePath.LastIndexOf('.') + 1).ToLower())
{
case "png":
ipt = ImagePartType.Png;
break; //TODO: might not be correct. Was : Exit Select
break;
case "jpg":
case "jpeg":
ipt = ImagePartType.Jpeg;
break; //TODO: might not be correct. Was : Exit Select
break;
case "gif":
ipt = ImagePartType.Gif;
break; //TODO: might not be correct. Was : Exit Select
break;
default:
return;
}
if (wsp.DrawingsPart == null)
{
//----- no drawing part exists, add a new one
dp = wsp.AddNewPart<DrawingsPart>();
imgp = dp.AddImagePart(ipt, wsp.GetIdOfPart(dp));
wsd = new WorksheetDrawing();
}
else
{
//----- use existing drawing part
dp = wsp.DrawingsPart;
imgp = dp.AddImagePart(ipt);
dp.CreateRelationshipToPart(imgp);
wsd = dp.WorksheetDrawing;
}
using (var fs = new FileStream(sImagePath, FileMode.Open))
{
imgp.FeedData(fs);
}
var imageNumber = 1;
if (imageNumber == 1)
{
var drawing = new Drawing();
drawing.Id = dp.GetIdOfPart(imgp);
ws.Append(drawing);
}
var nvdp = new NonVisualDrawingProperties();
nvdp.Id = new UInt32Value(Convert.ToUInt32(1024 + imageNumber));
nvdp.Name = "Picture " + imageNumber.ToString();
nvdp.Description = "Picture";
var picLocks = new PictureLocks();
picLocks.NoChangeAspect = true;
picLocks.NoChangeArrowheads = true;
var nvpdp = new NonVisualPictureDrawingProperties();
nvpdp.PictureLocks = picLocks;
var nvpp = new NonVisualPictureProperties();
nvpp.NonVisualDrawingProperties = nvdp;
nvpp.NonVisualPictureDrawingProperties = nvpdp;
var stretch = new Stretch();
stretch.FillRectangle = new FillRectangle();
var blipFill = new BlipFill();
var blip = new Blip();
blip.Embed = dp.GetIdOfPart(imgp);
blip.CompressionState = BlipCompressionValues.Print;
blipFill.Blip = blip;
blipFill.SourceRectangle = new SourceRectangle();
blipFill.Append(stretch);
var t2d = new Transform2D();
var offset = new Offset();
offset.X = 0;
offset.Y = 0;
t2d.Offset = offset;
var bm = new Bitmap(sImagePath);
var extents = new Extents();
if (width == null)
{
extents.Cx = Convert.ToInt64(bm.Width)*
Convert.ToInt64(Math.Truncate(Convert.ToSingle(914400)/bm.HorizontalResolution));
}
else
{
extents.Cx = width;
}
if (height == null)
{
extents.Cy = Convert.ToInt64(bm.Height)*
Convert.ToInt64(Math.Truncate(Convert.ToSingle(914400)/bm.VerticalResolution));
}
else
{
extents.Cy = height;
}
bm.Dispose();
t2d.Extents = extents;
var sp = new ShapeProperties();
sp.BlackWhiteMode = BlackWhiteModeValues.Auto;
sp.Transform2D = t2d;
var prstGeom = new PresetGeometry();
prstGeom.Preset = ShapeTypeValues.Rectangle;
prstGeom.AdjustValueList = new AdjustValueList();
sp.Append(prstGeom);
sp.Append(new NoFill());
var picture = new Picture();
picture.NonVisualPictureProperties = nvpp;
picture.BlipFill = blipFill;
picture.ShapeProperties = sp;
var pos = new Position();
pos.X = x;
pos.Y = y;
var ext = new Extent();
ext.Cx = extents.Cx;
ext.Cy = extents.Cy;
var anchor = new AbsoluteAnchor();
anchor.Position = pos;
anchor.Extent = ext;
anchor.Append(picture);
anchor.Append(new ClientData());
wsd.Append(anchor);
wsd.Save(dp);
}
catch (Exception ex)
{
//or do something more interesting if you want
throw ex;
}
}
public static void InsertImage(MemoryStream stream, long x, long y, string sImagePath)
{
using (var mySpreadsheet = SpreadsheetDocument.Open(stream, true))
{
var workbookPart = mySpreadsheet.WorkbookPart;
var sheets = mySpreadsheet.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
var relationshipId = sheets.First().Id.Value;
var worksheetPart = (WorksheetPart) mySpreadsheet.WorkbookPart.GetPartById(relationshipId);
var workSheet = worksheetPart.Worksheet;
//Dim sheets As worksheetpart = mySpreadsheet.WorkbookPart.Workbook.
//For each sheet, display the sheet information.
long width = 9525*193;
long height = 9525*80;
InsertImage(workSheet, x, y, width, height, sImagePath);
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem könnte sein, dass Sie zugeordnet imageNumber werden zum 1.
Vielleicht finden Sie diese, um zu helfen:
Auch, der Quellcode sieht verdächtig ähnlich zu dem, was ich gepostet auf meinem blog-post. Das ist ok. Auch finden Sie vielleicht SpreadsheetLight hilfreich zu sein. Es ist ein spreadsheet-Bibliothek, wie ClosedXml, und es können Bilder einfügen, einfach nur gut. Disclaimer: ich schrieb SpreadsheetLight.
hahahaha dieser geknackt me up, wenn ich es sah. Ich mache buchstäblich genau dasselbe.
Ich bin die Erzeugung einer Kalkulationstabelle mit geschlossenen XML und dann Bilder einfügen mit Vincent code.
Leider habe ich das gleiche problem, aber es ist nicht im Zusammenhang mit der imageNumber erklärt wird, wie 1
Allerdings habe ich einen workaround gefunden:
nachdem Sie eingefügt haben die Bilder ganz einfach wieder öffnen Sie das Dokument mit geschlossenen xml und speichern Sie es erneut.
Ich bin einfach mit dieser
Danach sollte es öffnen, ohne ein problem.
Hoffe, dies hilft jemand anderes mit einem ähnlichen Problem
EDIT:
War ich in der Lage, dieses problem vollständig, indem Sie diese segment:
ändern
ws.Append(drawing);
zuDann wird es kurz vor der letzten Kind, das war für mich
<x:tableParts count="0"/>
setzen es nach zu sein scheint, was das problem verursacht
Ich hatte ein ähnliches problem. Wenn ich ein OpenXML Productivity Tools vergleichen zwischen den ClosedXML-Dokument erstellt und eine, wo ich das Bild in Excel habe ich festgestellt, dass ClosedXML eingefügt, einige element-Knoten, die, während Sie waren nicht ungültig, schien das Blatt mit der Zeichnung-element ist ungültig. Ich entfernt die Elemente und die Tabelle mit dem Bild öffnet sich fein in Excel. Es ist eine kluge, aber es funktioniert. Dieser code geht an der Spitze der InsertImage Methode:
HTH
Angus
OpenXml ist nicht die einfachste Sache, um Ihren Kopf herum wickeln.
Das einzige, was Sie nicht sagen ist, dass die Reihenfolge der Elemente ist oft wichtig. Wie bereits erwähnt, ist die index-Nummer ist nicht die Ursache, Sie müssen neu -, um Ihre xml-tags, so dass die
tableParts
element kommt vor dasdrawing
element.Alternativ, da du keine TableParts, können Sie einfach entfernen Sie die element insgesamt
Also aus deinem Beispiel
Wenn Sie schreiben, um eine neue Excel-Datei den folgenden code in Ordnung ist:
Wenn Sie schreiben, um eine vorhandene Datei, die vielleicht schon eine Zeichnung Abschnitt obwohl (aber keine Bilder...die Formen scheinen zu sein, Teil der Zeichnung Abschnitt), dann bewirkt dies, dass Ihr Dokument für die Validierung fehlschlagen und sogar scheitern, vollständig zu öffnen.
Ich behoben, indem Sie Folgendes tun:
Scheint es nur 1 Zeichnung Abschnitt pro Arbeitsblatt...dauerte eine Weile, um die Spur das problem, da es nicht sofort offensichtlich ist, leider.