惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
人人都是产品经理
人人都是产品经理
罗磊的独立博客
博客园 - 聂微东
雷峰网
雷峰网
量子位
美团技术团队
V
V2EX
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
The Cloudflare Blog
爱范儿
爱范儿
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
Jina AI
Jina AI

博客园 - soonssa

离线使用Visual Studio的Javascript Prettier插件 在各页顶端以标题行形式重复出现无效 转:Windows 8上强制Visual Studio以管理员身份运行 读取Excel是数据截断问题 jQuery UI Autocomplete 1.8.16中文输入修正 一次诡异的http404错误的解决 Sqlite Expert Professional 3 破解 复制SqlServer备份到其他计算机,实现异地备份 - soonssa - 博客园 贝电BD201 ADSL MODEM 设置 jquery UI Webservice的安全问题 从Enterprise Library获取的数据的DataGridView的中文排序 ASPNET内置身份认证,用户身份串门 media palyer activex播放问题 莫名其妙的“文件不存在”错误 - soonssa - 博客园 CuteEditor允许插入javascipt语句 - soonssa - 博客园 两个客户端操作TreeView节点CheckBox的小例子(转) FixedDialog模式 图书馆专业英语词汇
将word表格中数据导出到Excel
soonssa · 2012-05-19 · via 博客园 - soonssa

  最近项目有一个需求,将多个word文件中的表格内容导入到Excel中,以方便下一步的处理,表格的格式是相同的。在网上找了很多资料,终于使用OpenXML SDK实现了,在此也把源代码分享给大家。

  主要参考文章 http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/01/6454.aspx

  关键代码:

  一、将DOC格式文件转为DOCX:

  因为OpenXML SDK只支持DOCX格式文件,因此首先要把DOC格式文件转为DOCX。

        /// <summary>
        /// 格式转换 DOC -> DOCX
        /// </summary>
        /// <param name="pathSource"></param>
        /// <param name="pathTarget"></param>
        public static void DocToDocx(string pathSource, string pathTarget)
        {
            object missing = System.Reflection.Missing.Value;
            Word.Application wordApp = new Word.Application();
            wordApp.Visible = false;
            Word.Document doc = null;
 
            object path1 = pathSource;
 
            doc = wordApp.Documents.Open(ref path1,
                ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing);
 
            object path2 = pathTarget;
            object fileType = Word.WdSaveFormat.wdFormatDocumentDefault;
            object compatibilityMode = Word.WdCompatibilityMode.wdWord2010;
 
            if (doc.SaveFormat == (int)Word.WdSaveFormat.wdFormatDocument)
            {
                doc.SaveAs2(ref path2, ref fileType,
                    ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref compatibilityMode);
            }
 
            if (doc != null) doc.Close(ref missing, ref missing, ref missing);
            wordApp.Quit(ref missing, ref missing, ref missing);
        }
 

  二、从DOCX文件中提取表格、行、单元格及内容

    public static class DocxTableExt
    {
        public static Table[] GetTables(this Body body)
        {
            return body.Elements<Table>().ToArray();
        }
 
        public static TableRow[] GetTableRows(this Table tbl)
        {
            return tbl.Elements<TableRow>().ToArray();
        }
 
        public static TableCell[] GetTableCells(this TableRow tr)
        {
            return tr.Elements<TableCell>().ToArray();
        }
 
        public static string GetTableCellContent(this TableCell td)
        {
            return string.Join("\n", td.Elements<Paragraph>().Select(o => o.InnerText).ToArray());
        }
    }

  三、根据配置文件提取对应单元格数据放到DataRow中

        /// <summary>
        /// 从word表格中提取对应数据到数据行中
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="pathSource"></param>
        /// <param name="xmlConfig"></param>
        /// <returns></returns>
        public DataRow CreatRow(DataTable dt, string pathSource, XmlConfig xmlConfig)
        {
            DataRow dr = dt.NewRow();
 
            using (WordprocessingDocument doc = WordprocessingDocument.Open(pathSource, false))
            {
                var tables = doc.MainDocumentPart.Document.Body.GetTables();
                for (int tableIndex = 0; tableIndex < tables.Length; tableIndex++)
                {
                    Table table = doc.MainDocumentPart.Document.Body.GetTables()[tableIndex];
                    var rows = table.GetTableRows();
                    for (int rowIndex = 0; rowIndex < rows.Length; rowIndex++)
                    {
                        var cells = rows[rowIndex].GetTableCells();
                        for (int columnIndex = 0; columnIndex < cells.Length; columnIndex++)
                        {
                            foreach (CellClass cell in xmlConfig.Import)
                            {
                                if ((tableIndex == cell.TableIndex - 1) && (rowIndex == cell.RowIndex - 1) && (columnIndex == cell.ColumnIndex - 1))
                                {
                                    dr[cell.Title] = cells[columnIndex].GetTableCellContent();
                                }
                            }
                        }
                    }
                }
            }
 
            return dr;
        }
    }

  四、配置文件示例

<?xml version="1.0" encoding="utf-8"?>
<XmlConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Import>
        <Item Title="姓名" Table="1" Row="1" Column="2" />
        <Item Title="性别" Table="1" Row="2" Column="2" />
        <Item Title="单位" Table="1" Row="8" Column="4" />
        <Item Title="工作简历" Table="1" Row="9" Column="2" />
    </Import>
    <Export RowStart="1" ColumnStart="1" />
</XmlConfig>

  说明:

  <Item Title="姓名" Table="1" Row="1" Column="2" /> 表示将word中第1个表格的第1行第2列处的数据提取到Excel中姓名列

  <Export RowStart="1" ColumnStart="1" /> 表示导出的Excel数据从第1行第1列开始

  五、下载

  程序  源代码