gpt4 book ai didi

asp.net-mvc - 如何将内存中的图表(或图像)放入内存中的 OpenXML 文档中?

转载 作者:行者123 更新时间:2023-12-01 04:05:05 26 4
gpt4 key购买 nike

我在尝试将图表添加到内存中的 MemoryStream 时遇到了噩梦。

我正在使用 OpenXML 即时创建一个 Word 文档,并且我有一个图表,该图表也是从数据库中的数据动态生成的。

我从数据库中以字节数组的形式获取模板,将其传递到一个方法中,该方法还接受一个包含一堆数据的业务对象来填充该模板中保存的书签。

这是方法:

public Stream Parse(byte[] array, AudiometryReport AudReport)
{

using (MemoryStream Stream = new MemoryStream())
{
Stream.Write(array, 0, (int)array.Length);
Stream.Position = 0;

using (document = WordprocessingDocument.Open(Stream, true))
{
XDocument doc = document.MainDocumentPart.GetXDocument();

List<XElement> bookmarks = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkStart")
.ToList();

PropertyInfo[] reportInfo = AudReport.GetType().GetProperties();

foreach (XElement bm in bookmarks)
{
try
{

if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);

var element = AddImageToDocument(document.MainDocumentPart, partId);
//var element = InsertImageXElement(partId);

//bm.ReplaceWith(new XElement(w + "r", element));
}
else
{
string val = reportInfo.Single(x => x.Name == bm.LastAttribute.Value).GetValue(AudReport, null).ToString();

bm.ReplaceWith(new XElement(w + "r",
new XElement(w + "t", val)));
}
}
catch
{ }
}

document.MainDocumentPart.PutXDocument();
//foreach (BookmarkStart bm in (IEnumerable<BookmarkStart>)document.MainDocumentPart.Document.Descendants<BookmarkStart>())
//{
// if (bm.Name == "AudiometryChart")
// {
// // Insert the chart object here.
// //AddImage(document);
// }
// populateStaffDetails(AudReport.Report.Employee, bm);
// populateAudiometryDetails(AudReport, bm);
//}

}


MemoryStream s = new MemoryStream();
Stream.WriteTo(s);
s.Position = 0;
return s;
}

}

InsertImage 图像采用 MainDocumentPart 并从我从数据库流的图像中附加一个新的 ImagePart。我将该部分的 ID 传递回调用方法。
private string InsertImage(MainDocumentPart docPart)
{
//DrawingsPart dp = docPart.AddNewPart<DrawingsPart>();
//ImagePart part = dp.AddImagePart(ImagePartType.Png, docPart.GetIdOfPart(dp));
ImagePart part = docPart.AddImagePart(ImagePartType.Png);
Chart cht = new ChartBuilder().DoChart(Data, new string[] { "Left", "Right", "Normal" });

using (MemoryStream ms = new MemoryStream())
{
cht.SaveImage(ms, ChartImageFormat.Png);
ms.Position = 0;

part.FeedData(ms);
}

//int count = dp.ImageParts.Count<ImagePart>();
int count = docPart.ImageParts.Count<ImagePart>();


return docPart.GetIdOfPart(part);
}

最后一部分是一些严重的肮脏,据称需要将一个图像添加到一个 Word 文档中,但到底是什么——无论如何——这里是:
private Run AddImageToDocument(MainDocumentPart docPart, string ImageRelId)
{
string ImageFileName = "Audiometry Chart Example";
string GraphicDataUri = "http://schemas.openxmlformats.org/drawingml/2006/picture";

long imageLength = 990000L;
long imageHeight = 792000L;

var run = new Run(
new Drawing(
new wp.Inline(

new wp.Extent() { Cx = imageLength, Cy = imageHeight },

new wp.EffectExtent()
{
LeftEdge = 19050L,
TopEdge = 0L,
RightEdge = 9525L,
BottomEdge = 0L
},

new wp.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Inline Text Wrapping Picture",
Description = ImageFileName
},

new wp.NonVisualGraphicFrameDrawingProperties(
new a.GraphicFrameLocks() { NoChangeAspect = true }),

new a.Graphic(
new a.GraphicData(
new pic.Picture(

new pic.NonVisualPictureProperties(
new pic.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = ImageFileName },
new pic.NonVisualPictureDrawingProperties()),

new pic.BlipFill(
new a.Blip() { Embed = ImageRelId },
new a.Stretch(
new a.FillRectangle())),

new pic.ShapeProperties(
new a.Transform2D(
new a.Offset() { X = 0L, Y = 0L },
new a.Extents() { Cx = imageLength, Cy = imageHeight }),

new a.PresetGeometry(
new a.AdjustValueList()) { Preset = a.ShapeTypeValues.Rectangle }))

) { Uri = GraphicDataUri }))
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U
}
));

return run;
}

因此,我已经通过过早关闭解决了内存流导致问题的问题,并且可能还有其他十几个不必要的业余花园路径问题,但该图像不会显示在我的文档中。令人沮丧。现在非常欢迎建议或神圣的灵感。

(这个问题已经过大量编辑,所以有些答案可能与这个问题的措辞无关)。

最佳答案

我刚刚测试了你的 AddImageToDocument小测试中的功能
使用以下代码的场景:

string partId = ...

Run element = AddImageToDocument(newdoc.MainDocumentPart, partId);

Paragraph p = new Paragraph() { RsidParagraphAddition = "00EA6221", RsidRunAdditionDefault = "008D25CC" };

p.AppendChild(element);

newdoc.MainDocumentPart.Document.Body.Append(p);

// Save the word document here...

一切都按预期工作,图像显示在 Word 文档中。

然后我得出结论,你的代码中的问题一定是替换了 bookmarkStart标签和转换
Run (包含图像)到 XElement .

因此,我以以下方式修改了您的代码(使用 XElement.Parse 转换 OpenXmlElementXElement ):
foreach (XElement bm in bookmarks)
{
try
{
if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);

Run element = AddImageToDocument(document.MainDocumentPart, partId);

bm.ReplaceWith(XElement.Parse(element.OuterXml)); // Use XElement.Parse to convert an OpenXmlElement to an XElement.
}
else
{
... }
}
}
catch
{
}
}

图像现在显示在 Word 文档中。

然后我使用
OpenXml SDK 生产力工具,发现 bookmarkEnd标签仍然存在于文档中。

要删除这些标签,请使用以下代码:
List<XElement> bookmarksEnd = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkEnd")
.ToList();

foreach (XElement x in bookmarksEnd)
{
x.Remove();
}

关于asp.net-mvc - 如何将内存中的图表(或图像)放入内存中的 OpenXML 文档中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9982746/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com