我正在尝试在生成电子表格后将图像添加到由 closedxml 使用 openxml 生成的 excel 文档中(因为 closedxml 目前无法插入图像)。
我可以正确生成 excel 文件,并且打开正常,但是当我尝试将图像插入并尝试在 excel 中打开它时会出错。
我使用了一个小型控制台应用程序,发现错误是
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
-------------------------------------------
电子表格如下所示:
<?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>
采取
section out 似乎允许文件正确验证。
我也尝试过手动创建一个空白的 excel 文档并添加一个图像,它看起来非常相似:
<?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>
我注意到的一件事是它们没有生成的命名空间(x),但我不知道这是否导致问题。
谁能看到我错过了什么?
我用来插入图像的代码如下:
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);
}
}