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

时间:2024-01-14 16:13:08

首先讲需求:

从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();
}
}

源文件