After I got confused with the Office Open XML (OOXML) measuring units for a couple of hours, I thought I’d share what I found on it.
I order to avoid floating point calculations and still maintain high precision the format uses some odd measurement units. Don’t think you can get away with inches, centimeters or pixels!
UPDATE: I created a conversion tool for all those units, available here.
UPDATE 2: Just fixed the DNS, so the conversion tool should be available again quite soon 🙂
Twentieths of a point (dxa)
The main unit in OOXML is a twentieth of a point. This is used for specifying page dimensions, margins, tabs, etc.
The international default letter size is ISO 216 A4 (210x297mm ~ 8.3×11.7in) and expressed as this:
// pageSize: with and height in 20th of a point <w:pgSz w:w="11906" w:h="16838"/>
|20th of a Point||Points
As you see it doesn’t really come out even, but even enough. As you can see here, word processes files at 72dpi.
Half-points are used to specify font sizes. A font-size of 12pt equals 24 half points:
// run properties <w:rPr> // size value in half-points <w:sz w:val="24"/> </w:rPr>
Fiftieths of a Percent
This is used for relative measurements in some places. It can for example be used for specifying tables total with, cell with and margins.
<w:tbl> <w:tblPr> <!-- table width in 50th of a percent --> <w:tblW w:w="2500" w:type="pct"/> </w:tblPr> <w:tblGrid/> <w:tr> <w:tc> <w:p> <w:r> <w:t>Hello, World!</w:t> </w:r> </w:p> </w:tc> </w:tr> </w:tbl>
This prints a table that takes 50% of the available with. If you want to specify the with in twentieth of points instead, you have to use specify w:type=”dxa”.
0.5 * 5000 = 2500pct
EMUs (English Metric Unit)
EMUs are used for coordinates in vector-based drawings and embedded pictures. The EMU is a virtual unit to bridge both centimeters and inches. One inch equates to 914400 EMUs and a centimeter is 360000. Actually I found out that the number 914400 is calculated by (the least common multiple of 100 and 254) times 72. As I understand it, this ensures that you can convert forth and back between integer 100th inches, millimeters and pixels with out any floating points. Is that correct, anybody?
Since OOXML is too verbose, the full markup would just confuse even more. Lets say we have a picture that we want to fit into a table cell.
The cell with is 4,25cm which equals to 2410 dxa.
<w:tcW w:w="2410" w:type="dxa"/>
The original picture is 295x413px at 72dpi and is embedded using DrawingML. The target picture size in the document has to be specified twice. Once for the drawing canvas (extent) and a second time for the embedded picture itself.
When you try to draw this in word itself you’ll have a hard time to match the actual cell size. This version is set by manually calculating the target picture size.
<w:drawing> <wp:anchor ...> ... <!-- drawing canvas size --> <wp:extent cx="1530350" cy="2142490"/> ... <a:graphic> <a:graphicData> <pic:pic> ... <!-- shape properties --> <pic:spPr bwMode="auto"> <!-- 2D transform --> <a:xfrm> ... <!-- picture size --> <a:ext cx="1530350" cy="2142490"/> </a:xfrm> ... </pic:spPr> </pic:pic> </a:graphicData> </a:graphic> </wp:anchor> </w:drawing>
|20th of a Point||Points
Even though this is the most logical way to calculate it, it involves floating points. You can simply avoid those by calculating:
2410 * 914400 / 72 / 20 = 1530350
which can be simplified to:
2410 * 635 = 1530350
Since we want to maintain the aspect ratio of the original picture at 295:413 we have to calculate the height for the cell in dxas and for the pictures in EMUs.
The width-to-height-ratio for this picture is 1.4. So the height for the cell is 2410*1.4 = 3374 dxa and 3374*635 = 2142490 emu.
Thanks for reading! I hope this helps.
Very good article!! Congrats..
Well, do you know if is there a way to measure a paragraph size in centimeters?
My idea is to build a document, by filling blank spaces left on a page that has a big paragraph.. If I knew the paragraph size, I could organize the document to save pages, joining small paragraphs on the same page.
Nowadays I use the RTF with a RichTextBox, to do this.. But I want to migrate to the Open XML Format..
Thanks a lot,
I don’t think you can measure this “in memory”. Word does the layout on the fly. The only thing you can calculate is where word breaks the page – but this is only done on save within word. You’ll then find a in the run (http://openiso.org/Ecma/376/Part4/2.3)
Thanks so much for posting this. I’ve skimmed over it once, now i read it a bit slower 🙂 all i gotta say at this point is…wtf…but wth…bring it on MS 🙂
There seems to be a typo in the HTML at
There is one less than symbol too much before the the div called “info”.
I’m recently working on transforming HTML to WordML and what my recent problem is that I have font-size in percentage.
How can I make this work in WordML.
I’ve used something like
<w:sz w:val="120%" />
But this doesn’t work, and it doesn’t have any w:type property or something similar.
Do you know how to do this?
If I remember right, the only thing you can give a percentage-width in WordML is tables.
Thank you so much for writing this article and conversion tool. It is going to be very helpful for my current project. Thank you. Thank you. Thank you.
Pingback: When section breaks won’t change « Much ado about Office
Thanks for this. I’m sure you’ve saved me many hours trying calculate it myself.
Lars, you just saved my weekend. Thank you!
[Besides, the name of this blog is just pure genius]
Hi, i’ve been using Office Open XML. I’m trying to create a textbox but i’ve been stucked in the xy alignment of the thing.
I can create a textbox but, the XY position comes from a web page the size of a word document (in pixels), how can i convert the pixel values to point values used by open xml?
Column widths in Excel 2007/2010 don’t follow any of the above. The width units are defined in the OOXML Standard (section 188.8.131.52).
The column width number represents, roughly, the number of *characters* that would fit in that column, accounting for padding, and rounded to 1/256th.
Padding is always 2 pixels on each side of the cell, plus 1 pixel for the gridlines, so 5 pixels.
The width value you would use in the XML would be:
width = Truncate( (NumChars * MaxWidth + Padding) / MaxWidth * 256) / 256
Let’s say you want to fit an average of 10 characters into the cell.
First, you would need to know the maximum width of a digit (0-9) using the spreadsheet’s *default* font. For 11pt Calibri, the maximum width of a digit is 7 pixels at 96dpi. So:
width = Truncate( (10 * 7 + 5) / 7 * 256) / 256 = 10.7109375
Thank you very much! I haven’t fiddled with Excel and widths yet – but when I will, it will be great to have this resource! 🙂
its really helpful when you try to understand the units of OOXML.
when i calculate the width of table in its says me width is 110% , so if i use this width its make my page bigger than actual , so what should i do , am i use 100% if width is more than 100%. thanks
Actually I don’t know; just try it… 🙂
thank god someone figured all of this out…
Pingback: Open Office XML 單位換算 | 旅人的旅程
Pingback: An Informal Introduction to DOCX | Blockalerts
Pingback: XML Hacking: Graduated Color Table Borders - Office Best Practices
Anybody have an idea of what is a a:ST_PositivePercentage, I know it is use to calculate the segments in a dash line. but it just does not make any sense to me.
Could you comment on why avoiding floating point calculations of such paramount importance that all of this complexity is justified? Is it the rouding issues, is it peformance, is it legacy from a time when perfomance was an issue?
Good question. No idea 😀
I have a small doubt.
I am working in xml transformation. How to change col to .How to calculate the width Value.
Great article on the open XML dimension calculation. It helps me a lot to insert image into word.
Pingback: Automatic generation of Microsoft Word files in engineering – Parametric Geometry Solutions Blog
The unit conversion tool is not working. Can you please check it ?
It seems the page loading is due to an error that’s why tool didn’t work.
It seems to work fine for me:
What problems are you experiencing?
Now it is working fine for me. Previously when I type value in textbox Unit conversion Didn’t work but it seems to be fixed now Thanks.
The unit conversion tool is not working. Getting an Uncaught error Exception in js in the console. Can you pls Check
Getting an Unexpected Error Exception in console & tool is not working. Can you pls check ?
Error: Must call google.charts.load before google.charts.setOnLoadCallback jsapi:89:298
Error: Module “search” is not supported.
It is not working even now, unit conversion is not working for any value I type in tool.
I dont know what is wrong with moderation. I posted multiple comments about Unit conversion tool not working issue but all are removed. What is happening ?
Tool is not working kindly pls Check
Tool doesn’t work
tool doesn’t work any more. it’s abandoned.
Pingback: Convert Google slides EMU units to pixels - API - Tutorial Guruji
Pingback: Convert Google slides EMU units to pixels – API – Java