python word 公式转png图片处理方式

      因项目中需要导入word文档,但其中存在的公式,系统不支持,但又需要导入进系统,之前都是手动截图后再重新插进去,关键时候上千章试卷要进行截图也很耗时间,所以研究了一下转换方式

 

      首先通过将docx后缀改成zip解压后可以发现,公式分成两部分,一部分是.wmf的矢量图文件,一个是objectbin文件,但实际通过画图打开矢量图后发现公式已经可以完整显示出来了,那需要解决的关键部分就是.wmf转.png文件就行了。最开始采用了java来做,但发现通过wmf转svg再转png,一些符号会显示错误,例如微积分符号,可能和格式或者转换方式有关,故放弃。偶然间通过画图将矢量图wmf另存为png时发现所有符号都是显示正确的,那么C#中肯定存在可以完成转换的方式,果然,翻阅一些资料后发现wmf可以通过图元文件写入位图,最后再将图像信息存入文件中就可以很方便的完成转换了,代码如下:

             

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;

namespace Project1
{
    class Class2
    {
        static void Main(string[] args)
         {
             String FileName = args[0];
             using (System.Drawing.Imaging.Metafile img = new System.Drawing.Imaging.Metafile(FileName))
             {
                 System.Drawing.Imaging.MetafileHeader header = img.GetMetafileHeader();
                 float scale = header.DpiX / 96f;
                 using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap((int)(scale * img.Width / header.DpiX * 100), (int)(scale * img.Height / header.DpiY * 100)))
                 {
                     using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
                     {
                         g.Clear(System.Drawing.Color.White);
                         g.ScaleTransform(scale, scale);
                         g.DrawImage(img, 0, 0);
                     }
                     bitmap.Save(@args[1], System.Drawing.Imaging.ImageFormat.Png);
                 }
             }
             Console.WriteLine("转换完成");
         }
    }
}

   然后通过pydocx进行读取后发现公式这部分是存储在run中的,那接下来只需要提取原图片进行转换后再插回去就可以了

 首先是通过遍历run中的xml节点,遍历函数如下,通过run.element可以获取run的xml节点,之后通过遍历函数进行遍历,公式是存储在

节点tag "{urn:schemas-microsoft-com:vml}imagedata"中,之后通过提取属性{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id来获得对应的资源id,然后通过资源id在

document.part.rels[资源id]中提取对应的资源,如果contenttype为image/x-wmf则进行转换,之后将run清空后(run.clear)通过run.add_picture插入转换后图片即可,这种转换可以最大程度的保留结构,避免丢东西

def iter_block_items(parent):
    """
      遍历节点
    """
    #document为主节点
    if type(parent)==document.DocumentPart:
        parent_elm = parent.element.body
    else:
        parent_elm=parent

    for child in parent_elm.iterchildren():
        #print(type(child))
        yield child
        for child2 in iter_block_items(child):
            yield child2

后记:

1.目前仅docx,doc文件需强行转换为docx后在进行处理

2.关于图片大小,目前可以通过两种方式进行

  1)通过提取"{urn:schemas-microsoft-com:vml}shape"的内容,大致格式为

"""'height:13.95pt;width:42.95pt;'""",提取对应的pt长度,换算为Inches需要除以72

  2)可能存在第一种方法没有获取到长度的,则需要通过Image.open打开图片获取图片像素大小

在转化为Inches即可(大致为width or height/缩放比率*72,缩放比率不太好找,需要自己摸索,大致上用37的花,目前见过的公式都转出来偏小一点)

3.新版本word公式不再是图片的不支持

 

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值