• 【.net 深呼吸】导出 Office 文档中的图片


    我们常用的 Office 文档其实就三种——Word、Excel、PowerPoint,分别对应的扩展名为:.docx、.pptx、.xlsx。

    许多教程都告诉我们,要提取这些文件中的图片(其实像视频之类的媒体文件也一样),可以把文档的后缀名改为 .zip,然后打开,在 media 目录下就能找到文档中插入的图片文件。

    要是嫌手动操作麻烦,其实我们完全可以用代码来完成。.net 类库自带可以操作 zip 压缩文档的 API,所以,我们不需要去找第六方组件。

    好,F话少说,咱们开始吧,其实很是简单的。

                try
                {
                    ZipArchive zdoc = ZipFile.OpenRead(txtInput.Text);
                    // 搜索
                    foreach (ZipArchiveEntry et in zdoc.Entries)
                    {
                        // 分析文件后缀
                        if (et.Name.Contains(".jpg") || et.Name.Contains(".jpeg") || et.Name.Contains(".png"))
                        {
                            listBox1.Items.Add(et.FullName);
                            // 把文件实体复制到外部文件中
                            using (Stream strm = et.Open())
                            {
                                string path = BuildPath(txtOutput.Text, et.Name);
                                FileStream fsout = File.Open(path, FileMode.OpenOrCreate);
                                strm.CopyTo(fsout);
                                fsout.Close();
                            }
                        }
                    }
                }
                catch(Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"EXCEPTION: {ex.Message}");
                    MessageBox.Show("你的人品值不足,请及时充值。");
                }
                finally
                {
                    ……
                }

    注意,你要引入以下两个程序集:

    System.IO.Compression

    System.IO.Compression.FileSystem

    我们直接把 Office 文件当成zip文件来处理就行了,调用 ZipFile 类的 OpenRead 方法(静态),可以以只读方式打开文件,我们这里只要读出图片文件就行了,所以只读方式打开就够了。打开文件后,返回一个 ZipArchive 实例,它表示一个zip文档的实例。

    压缩档中的文件是以一个个实体的形式存放的,每个实体用一个 ZipArchiveEntry 实例封装,所以我们要通过循环,筛选出后缀为 .jpg、.jpeg、.png的文件。

    找出相关的实体后就好办了,直接将文件流复制到输出流中即可。

                            using (Stream strm = et.Open())
                            {
                                string path = BuildPath(txtOutput.Text, et.Name);
                                FileStream fsout = File.Open(path, FileMode.OpenOrCreate);
                                strm.CopyTo(fsout);
                                fsout.Close();
                            }

    这里用到一个 BuildPath 方法,是个自定义方法,目的是组装文件名,如果文件已存在,就生成像 abc(1)  abc(2) 这样的文件名。代码如下。

            /// <summary>
            /// 该方法用来生成新的路径
            /// </summary>
            /// <param name="dir">要存放的目录</param>
            /// <param name="fn">实体文件名</param>
            /// <returns></returns>
            string BuildPath(string dir, string fn)
            {
                string tmpPath = Path.Combine(dir, fn);
                int i = 1; //这个值用来自增长
                // 循环,直到生成不重复的文件名
                // 如果文件名已存在,就生成 xxx(1)、xxx(2)、xxx(3)这样的文件名
                while (File.Exists(tmpPath))
                {
                    // 不含后缀的文件名
                    string fn_1 = Path.GetFileNameWithoutExtension(fn);
                    // 扩展名,如.txt
                    string fn_ext = Path.GetExtension(fn);
                    // 重组文件名
                    string _fn = $"{fn_1}({i}){fn_ext}";
                    // 重组路径
                    tmpPath = Path.Combine(dir, _fn);
                    i++;
                }
                return tmpPath;
            }

    好了,就这么简单,完事了。

    具体的,大家可以看源代码。

    点击下载源代码

  • 相关阅读:
    docker国内镜像地址
    springBoot+websocket集群系列知识
    多个idea项目使用同一个tomcat
    nginx+tomcat遇到的https重定向到http问题
    设置常用错误页面自定义显示
    mysql关于索引的一些零碎知识点(持续更新)
    Idea使用Lombok简化实体类代码
    mysql索引分类及实现原理
    使用SpringSession和Redis解决分布式Session共享问题
    HashMap ConcurrentHashMap解读
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/7324584.html
Copyright © 2020-2023  润新知