首先讲需求:

从word文件中读表格里的数据,然后插入数据库中。word文件中的表格是带有标题的,把标题读出来,进行匹配数据库。

需求分析:

word2007底层是以xml文件存储的,所以分析xml的格式,进行读取相应数据。

表格数据如下:

表 1 分类统计表

分类

总计

1类

2类

软件

4

3

7

硬件

5

6

11

word底层xml组成如下分析:

<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:pStyle w:val="a4"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
<w:ind w:firstLineChars="0"/>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>分类统计表</w:t>
</w:r>
</w:p> <w:tbl>
<w:tblPr>
<w:tblStyle w:val="a3"/>
<w:tblW w:w="0" w:type="auto"/>
<w:jc w:val="center"/>
<w:tblBorders>
<w:left w:val="none" w:color="auto" w:space="0" w:sz="0"/>
<w:right w:val="none" w:color="auto" w:space="0" w:sz="0"/>
</w:tblBorders>
<w:tblLook w:val="04A0" w:noVBand="1" w:noHBand="0" w:lastColumn="0" w:firstColumn="1" w:lastRow="0" w:firstRow="1"/>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="2074"/>
<w:gridCol w:w="2074"/>
<w:gridCol w:w="2074"/>
<w:gridCol w:w="2074"/>
</w:tblGrid>
<w:tr w:rsidR="009F1A99" w:rsidTr="009F1A99">
<w:trPr>
<w:jc w:val="center"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vMerge w:val="restart"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="4148" w:type="dxa"/>
<w:gridSpan w:val="2"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>分类</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vMerge w:val="restart"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>总计</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="009F1A99" w:rsidTr="009F1A99">
<w:trPr>
<w:jc w:val="center"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vMerge/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>1类</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>2类</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vMerge/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="009F1A99" w:rsidTr="009F1A99">
<w:trPr>
<w:jc w:val="center"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>软件</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>4</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>3</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>7</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="009F1A99" w:rsidTr="009F1A99">
<w:trPr>
<w:jc w:val="center"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>硬件</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>5</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>6</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2074" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidRDefault="009F1A99" w:rsidR="009F1A99" w:rsidP="009F1A99">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>11</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</w:tbl>

分析上面的表格标签可以得出如下结论:

段落标签:p

段落内容:t

表格标签:tbl

表格行标签:tr

表格标签:tc

水平合并标签:gridSpan  属性:w:val等于合并项

垂直合并标签:vMerge 属性:w:val等于restart表示垂直合并的开始

下面是读取代码:

头文件:

#ifndef READERXML_H
#define READERXML_H //定义一个单元格属性
class Cell
{
public:
Cell() : m_value(""), m_hSpan(), m_vSpan(false)
{ } QString m_value; //表格内容
int m_hSpan; //水平合并数
bool m_vSpan; //是否垂直合并
QList<QList<Cell *> > m_subTable; //是否存在子表格
}; class ReaderXml
{
public: //对外接口 参数1:xml文件名 参数2:表格标题 参数3:表格数据
void reader(const QString &filename, QStringList &tableHeader, QList<QList<QStringList> > &tableData); private:
void getParagraph(QString &header); //获取段落
void getTableData(QList<QStringList> &data); //读取表格数据
void getTableLine(QList<Cell> &tableLine); //读取表格一行
void getCell(Cell &cell); //读取一个单元格 private:
QXmlStreamReader m_reader;
}; #endif // READERXML_H

头文件

源文件

#include "StdAfx.h"
#include "ReaderXml.h" void ReaderXml::reader( const QString &filename, QStringList &tableHeader, QList<QList<QStringList> > &tableData )
{
QFile file(filename);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
return ;
}
m_reader.setDevice(&file); QStringList strList;
m_reader.readNext();
while(!m_reader.atEnd())
{
if(m_reader.isStartElement())
{
if(m_reader.name() == "p") //段落标签
{
QString str;
getParagraph(str);
strList.append(str);
}
else if(m_reader.name() == "tbl") //表格标签
{
QList<QStringList> data;
getTableData(data);
tableData.append(data);
tableHeader.append(strList.last()); //表格上的段落是表格的标题
}
}
m_reader.readNext();
} m_reader.clear();
file.close();
} void ReaderXml::getParagraph( QString &header )
{
m_reader.readNext();
while(!m_reader.atEnd())
{
if(m_reader.isStartElement())
{
if(m_reader.name() == "t") //数据
{
header += m_reader.readElementText();
}
}
else
{
if(m_reader.name() == "p")
{
return ;
}
}
m_reader.readNext();
}
} void ReaderXml::getTableData( QList<QStringList> &data )
{
m_reader.readNext();
while(!m_reader.atEnd())
{
if(m_reader.isStartElement())
{
if(m_reader.name() == "tr") //表格行标签
{
QList<Cell> lineData;
QStringList strList;
getTableLine(lineData);
for(int i = , len = lineData.size(); i != len; ++i)
{
if(lineData[i].m_vSpan && !data.isEmpty()) //表格是否存在垂直合并的情况
lineData[i].m_value = data.last().at(i); for(int j = ; j != lineData[i].m_hSpan; ++j) //表格是否存在水平合并的情况
strList.append(lineData[i].m_value);
}
data.append(strList);
}
}
else
{
if(m_reader.name() == "tbl")
{
return ;
}
}
m_reader.readNext();
}
} void ReaderXml::getTableLine( QList<Cell> &tableLine )
{
m_reader.readNext();
while(!m_reader.atEnd())
{
if(m_reader.isStartElement())
{
if(m_reader.name() == "tc") //单元格标签
{
Cell cell;
getCell(cell);
tableLine.push_back(cell);
}
}
else
{
if(m_reader.name() == "tr")
{
return ;
}
}
m_reader.readNext();
}
} void ReaderXml::getCell( Cell &cell )
{
m_reader.readNext();
while(!m_reader.atEnd())
{
if(m_reader.isStartElement())
{
if(m_reader.name() == "t") //数据标签
{
cell.m_value += m_reader.readElementText();
}
else if(m_reader.name() == "gridSpan") //水平合并标签
{
cell.m_hSpan = m_reader.attributes().value("w:val").toString().toInt(); //合并数
}
else if(m_reader.name() == "vMerge") //垂直合并标签
{
cell.m_vSpan = true;
}
}
else
{
if(m_reader.name() == "tc")
{
return ;
}
}
m_reader.readNext();
}
}

源文件

从一个word文件中读取所有的表格和标题(1)的更多相关文章

  1. 从一个word文件中读取所有的表格和标题(2)

    上一篇文章主要讲了从word底层xml中获取表格和标题的方法,但是存在一个问题:word文件必须是docx格式的.如果为doc格式的,可以有两种解决方案: 一.把doc文件转换成docx格式文件,用上 ...

  2. 编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内

    查看本章节 查看作业目录 需求说明: 在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字"[ 来自新华社 ]",保存到一个新的 txt 文件内 实现思路: 创建 Sa ...

  3. 条形码的应用三-----------从Excel文件中读取条形码

    条形码的应用三------从Excel文件中读取条形码 介绍 上一篇文章,我向大家展示了生成多个条形码并存储到Excel文件中的一个方法.后来我又有了个想法:既然条码插入到excel中了,我可不可以从 ...

  4. 【jacob word】使用jacob,合并多个word为一个word文件

    将几个word文件合并到一个word文件,使用注意点: 1.后面附项目运用的jar包jacob-1.9, 2.并且jacob运用中,需要将附件内的jacob.dll放到windows/system32 ...

  5. java:利用java的输入/输出流将一个文件的每一行+行号复制到一个新文件中去

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  6. Java将对象保存到文件中/从文件中读取对象

    1.保存对象到文件中 Java语言只能将实现了Serializable接口的类的对象保存到文件中,利用如下方法即可: public static void writeObjectToFile(Obje ...

  7. 从PCD文件中读取点云数据

    博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=84 在本小节我们学习如何从PCD文件中读取点云数据. 代码 章例1文件夹中, ...

  8. 【Python】从文件中读取数据

    从文件中读取数据 1.1 读取整个文件 要读取文件,需要一个包含几行文本的文件(文件PI_DESC.txt与file_reader.py在同一目录下) PI_DESC.txt 3.1415926535 ...

  9. Python自动化测试框架——数据驱动(从文件中读取)

    学过编程的伙伴们都知道,数据不仅可以从代码中读取,还可以从文件中读取. 今天小编就简要的介绍一下从文件中读取数据,并应用到自动化测试中方法. 先来展示下接下来将要用到的文件在项目中的结构 从txt文件 ...

随机推荐

  1. deepin 环境变量配置加载顺序

    加载顺序,默认是没有 .bash_profile 文件 1. non-login 方式 ~$ su deepin run /ect/bash.bashrc run .bashrc 2.login 方式 ...

  2. python中的“.T”操作

    其实就是对一个矩阵的转置 看代码: a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a.T array([[1, 4, 7], [2, 5, 8], [3, 6, ...

  3. php面试之数据结构和算法

    二.数据结构和算法 1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator接口)(腾讯) <?php class T ...

  4. EntityFrameworkCore v1.1.1 问题汇总

    随着宇宙第一IDE的最新版本发布[2017/3/7],AspNetCore 和EntityFrameworkCore(团队)都发布了最新的代码. 不过在我看来,这些到还不是最重要的.最重要的是dotn ...

  5. 使用questionsModel.values()后不能获取模型中的属性对应的外键属性值的解决方式

    class QuestionsModel(models.Model): author = models.ForeignKey(FrontUserModel,null=True) content = m ...

  6. 【Hdu3555】 Bomb(数位DP)

    Description 题意就是找0到N有多少个数中含有49. \(1\leq N \leq2^{63}-1\) Solution 数位DP,与hdu3652类似 \(F[i][state]\)表示位 ...

  7. 腾讯qq等级计算公式面试题

    就三道题大概是: 1. 推算出等级相应的天数 这个还比較简单,公式是:(b=2a+3)   a是等级, b是相应的天数 2. 推算出等级总共的天数 先看下规律 等级a 相应天数b 总天数s 1 5 5 ...

  8. 命令行界面下使用emca安装配置Oracle Database Control实战

    作为命令行忠有用户,server端软件的运维都倾向于使用命令或 脚本完毕,非常讨厌资源占用非常大的GUI.Oracle数据库作为重要的server端软件.其安装运维自然也全然支持纯命令行方式.虽然同一 ...

  9. char a[] = "ab\0123\098"; 求a的长度

      原因: \0表示后面的字符是八进制(\ddd); 8进制=10进制( 10是'\n' 的ASCII码): 当\0后面有数字,且数字范围在0~7之间时,为8进制转义.如'\012': 当\0后面没有 ...

  10. .Net 关于 InfoPath 的基本使用

    最近几天接触微软的  InfoPath 表单工具,结合VS 使用,遇到的一些问题与解决方法,记录一下,百度上的内容很少,或许我根本不知道咋搜,所有也留一个网页帮助自己使用当然使用的时候碰到了好几个坑: ...