草庐IT

c# - 将 .NET 像素转换为 OpenXML 格式的 Excel 宽度的公式

coder 2024-05-27 原文

我花了很多时间试图确定一个公式,以使用 OpenXML 格式将 .NET 像素转换为 Excel 列宽。我正在使用 EPPlus 生成 xmls 文档。我正在尝试确定要自动调整大小的列的宽度。我通过测量字符串然后尝试将其转换为 OpenXML 的列宽来获取像素数,我认为这是以字符为单位测量的。

我已经阅读了微软关于如何转换它的文档并尝试了他们建议的公式,但它甚至不准确:

http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx

这是我使用他们的公式的代码:

    public double GetCharacterWidth(string Text, Font f, Graphics g)
    {
        float MaxDigitWidth = g.MeasureString("0", f).Width;
        float Pixels = g.MeasureString(Text, f).Width;

        return ((Pixels - 5) / MaxDigitWidth * 100 + 0.5) / 100;
    }

有什么想法吗?

最佳答案

首先我们需要确定 Excel 如何进行转换(因为我们在 Excel 应用程序中手动更改大小):

//Use 7d to promote to double, otherwise int will truncate.
ExcelWidth = (Pixels - 12) / 7d +  1;//From pixels to inches.

警告:这些公式不适用于 0(零)宽度或像素。
对于这些情况,请使用“if”语句检查是否为零并返回零。

它也让我很困惑。我没有试图找出每个宽度的像素,而是查看了每个宽度整数之间的像素差异,发现它始终为 7。异常(exception)是 0 到 1 宽度;宽度 1.00 有 12 个像素。从那里我能够得出上面的公式,简单易行。

现在这些数字在 Excel 的世界中站得住脚,但如果您直接在 OpenXml 文档中设置列宽,情况就会略有不同。原因如下:在您链接到的文档中,关于 5 个像素的内容是这样说的:

There are 4 pixels of margin padding (two on each side), plus 1 pixel padding for the gridlines.

这意味着 Excel 假设您已将这 5 个像素计入您提供的宽度。当您在 Excel 中打开文档并调整列大小时,您会看到宽度比您设置的宽度小 5 个像素。

要对此进行调整,您可以按如下方式更新公式:

//Use 7d to promote to double, otherwise int will truncate.
OpenXmlWidth = (Pixels - 12 + 5) / 7d + 1;//From pixels to inches.

这回答了您问题的标题:
将 .NET 像素转换为 OpenXML 格式的 Excel 宽度的公式

如果您想知道如何计算列宽的近似值以根据单个单元格的内容(和字体)自动调整列,那么这是一个完全不同的问题。您提供的 Microsoft 链接提供的公式将不起作用。在一个单元格中输入 10 个句点,在另一列中输入 10 个大写字母 M。您会看到自动调整分别为您提供 41 像素和 129 像素。 ms 提供的公式没有考虑单个字符的宽度。换一种说法;他们派你去徒劳地追逐。

自动调整列的唯一方法是扫描列中的每一行,并根据使用的字符和字体计算文本的宽度。你会使用像我发现的东西 here .然后取最大值并用 5 填充。在 Web 环境中处理电子表格时,我会避免这种方法,因为您可能会导出数十万行和数十列 - 你明白了。最好的方法是为您的列设置一个最佳猜测宽度,并培训您的用户如何从 Excel 自动调整。

此致,
普通人


编辑 - 2011 年 10 月 26 日:

因为我觉得很慷慨,下面是一个如何为您的列获取近似宽度的示例。我宁愿避免对列中的所有行执行此操作,所以让我们将宽度(默认情况下)基于标题单元格中的值。下面是如何使用我之前链接到的示例来执行此操作。注意:这些是近似值,但足够接近。

using System.Drawing;
using System.Windows.Forms;//Add Reference.  Test on webserver first.
Font font = new Font("Calibri", 11.0f, FontStyle.Regular);
string header  = "Hello There World!";
int pxBaseline = TextRenderer.MeasureText("__", font).Width;
int pxHeader   = TextRenderer.MeasureText("_" + header + "_"), font).Width;
int pxColumnWidth = pxHeader - pxBaseline + 5;//Pad with 5 for Excel.

警告:如果您在使用 OpenXml 的同一位置使用此代码,则可能需要删除 System.Drawing 的“using”并完全限定“Font”和“FontStyle” "作为 System.Drawing.Font 和 System.Drawing.FontStyle。否则,您的编译器可能会将这些类误认为属于 DocumentFormat.OpenXml.Spreadsheet。

关于c# - 将 .NET 像素转换为 OpenXML 格式的 Excel 宽度的公式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7716078/

有关c# - 将 .NET 像素转换为 OpenXML 格式的 Excel 宽度的公式的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  5. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  6. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  7. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  8. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  9. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  10. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

随机推荐