![](/img/trans.png)
[英]How to insert a newline in PowerPoint (PPTX) in OpenXML / PresentationML / C#
[英]Calculate the size (Extents) of a text (TextBody) in OpenXML (PresentationML) PowerPoint (PPTX)
我想使用来自数据库的数据创建演示文稿。 我设法获得了在PowerPoint中打开的有效演示文稿(SDK 2.5的Open XML Productivity Tool在执行此操作方面有很大帮助)。 但是,如何计算文本框形状的大小? 我看到将值放在哪里,但是new Extents()
默认为零宽度和高度。 当我从现有演示文稿中获取一些Shape
值时,我可能会得到正确的高度(至少对于一行或固定行数的文本而言),但是文本会在右侧或底部溢出(取决于换行设置)。
另外,在TextBody
的BodyProperties
中插入NormalAutoFit
也无济于事-在OpenXML中不计算FontScale
和LineSpaceReduction
的必要值。
那么,用TextBody
设置Shape
的Extents
的最佳实践是什么?
是否有一个内置的方式来计算Extents
给定的TextBody
或Shape
? (一些内置方法的经验法则总比没有好。)
我知道PowerPoint会在进行任何更改后(至少对于更改前后的一堆幻灯片)重新计算NormalAutoFit
的值, NormalAutoFit
在进行更改之前开始演示文稿(或是否进行更改)没有帮助。是使用PowerPoint查看器启动的)。
这是一项艰巨(但可行)的任务。
经过多次实验,我发现System.Windows.Forms.TextRenderer中的文本度量方法给了我最好的结果。 这是WmlToHtmlConverter使用的文本度量功能。 您可以将WmlToHtmlConverter中的代码视为使用TextRenderer的一个示例。
这是我根据Eric White的WmlToHtmlConverter, 本文和this提出的代码 。 我用它来计算用于Word文档的OpenXml的文本水印和图像水印的TextBox的尺寸。
private static D.Size pixelsToEmus(int widthPx, int heightPx, double resDpiX, double resDpiY, int zoomX, int zoomY)
{
const int emusPerInch = 914400;
const int emusPerCm = 360000;
const decimal maxWidthCm = 16.51m;
var widthEmus = (int)(widthPx / resDpiX * emusPerInch) * zoomX / 100;
var heightEmus = (int)(heightPx / resDpiY * emusPerInch) * zoomY / 100;
var maxWidthEmus = (int)(maxWidthCm * emusPerCm);
if (widthEmus > maxWidthEmus)
{
var ratio = ((decimal)heightEmus / (decimal)widthEmus);
widthEmus = maxWidthEmus;
heightEmus = (int)(widthEmus * ratio);
}
return new D.Size(widthEmus, heightEmus);
}
public static D.Size GetTextSize(this CWatermarkItemBase watermark, string runText)
{
var fs = watermark.GetFontStyle();
var sz = watermark.FontSize;
var proposedSize = new D.Size(int.MaxValue, int.MaxValue);
D.Size sf;
using (var ff = new D.FontFamily(watermark.FontFamily))
{
try
{
using (var f = new D.Font(ff, (float)sz, fs))
{
const TextFormatFlags tff = TextFormatFlags.NoPadding;
sf = TextRenderer.MeasureText(runText, f, proposedSize, tff);
}
}
catch (ArgumentException)
{
try
{
const D.FontStyle fs2 = D.FontStyle.Regular;
using (D.Font f = new D.Font(ff, (float)sz, fs2))
{
const TextFormatFlags tff = TextFormatFlags.NoPadding;
sf = TextRenderer.MeasureText(runText, f, proposedSize, tff);
}
}
catch (ArgumentException)
{
const D.FontStyle fs2 = D.FontStyle.Bold;
try
{
using (var f = new D.Font(ff, (float)sz, fs2))
{
const TextFormatFlags tff = TextFormatFlags.NoPadding;
sf = TextRenderer.MeasureText(runText, f, proposedSize, tff);
}
}
catch (ArgumentException)
{
// if both regular and bold fail, then get metrics for Times New Roman
// use the original FontStyle (in fs)
using (var ff2 = new D.FontFamily("Times New Roman"))
using (var f = new D.Font(ff2, (float)sz, fs))
{
const TextFormatFlags tff = TextFormatFlags.NoPadding;
sf = TextRenderer.MeasureText(runText, f, proposedSize, tff);
}
}
}
}
}
D.Size s2 = pixelsToEmus(sf.Width, sf.Height, 96, 96, 100, 100);
return s2;
}
public static D.Size GetImageSize(this CWatermarkItemImage watermarkItem)
{
var img = new BitmapImage(new Uri(watermarkItem.FilePath, UriKind.RelativeOrAbsolute));
return pixelsToEmus(img.PixelWidth, img.PixelHeight, img.DpiX, img.DpiY, watermarkItem.ZoomWidth, watermarkItem.ZoomHeight);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.