我可以将图像设置为*不*自动调整大小吗?

Can I Set an Image to *Not* Auto-Resize?

我有一个 "template" Excel 文件,其中包含为布局设置的一些基本内容(一些合并的单元格、一些列宽等),然后 ClosedXML 使用它来填充数据。在基本层面上,它很简单:

var workbook = new XLWorkbook(filePath);
workbook.Worksheets.Single().Cell(1, 4).Value = someTextValue;
workbook.Worksheets.Single().Cell(1, 4).Style.Alignment.WrapText = true;
// set other values, etc.

整个过程涉及将文件复制到另一个流,返回它以从网络应用程序下载,诸如此类。

静态模板文件中的一个单元格有图像。该行上的另一个单元格需要自动扩展以适应带有回车 returns 的换行文本。当设置上面的 WrapText 属性 时,行的自动扩展工作正常。然而,image 也在扩展它的高度。 (因此变得明显扭曲。)

在文件本身中,我右键单击图像以设置其格式,并在 "Size & Properties" 下明确选择 "Don't move or size with cells"。但是,通过 ClosedXML 交互自动调整行的大小仍然会导致图像调整大小。

我尝试过的另一件事是以某种方式 "separate" 行中的图像,方法是将其放入文本框内。但是,图像和文本框似乎都在单元格上方 "float",并且图像不能放在文本框内(或者我不知道如何放置)。

ClosedXML 似乎对图像没有太多支持(除非我只是没有看到它)。在此设置中是否有任何方法可以防止此图像随行自动调整大小?

我遇到了类似的问题。我的解决方案是为图像使用绝对定位的锚点,出于某种原因你不能在 Excel 本身中这样做...

我使用与 here 中的代码类似的代码构建控制台应用程序以使用 OpenXML SDK 生成模板 Excel 文件。锚代码:

Position pos = new Position();
pos.X = 0;
pos.Y = 0;
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());

完整代码隐藏在代码片段中以备不时之需:

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";
   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 = 0;
   offset.Y = 0;
   t2d.Offset = offset;
   Bitmap bm = new Bitmap(sImagePath);
   //http://en.wikipedia.org/wiki/English_Metric_Unit#DrawingML
   //
   //
   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 = 0;
   pos.Y = 0;
   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();
 }
}