从一个word文件中读取所有的表格和标题(1)
首先讲需求:
从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)的更多相关文章
- 从一个word文件中读取所有的表格和标题(2)
上一篇文章主要讲了从word底层xml中获取表格和标题的方法,但是存在一个问题:word文件必须是docx格式的.如果为doc格式的,可以有两种解决方案: 一.把doc文件转换成docx格式文件,用上 ...
- 编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
查看本章节 查看作业目录 需求说明: 在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字"[ 来自新华社 ]",保存到一个新的 txt 文件内 实现思路: 创建 Sa ...
- 条形码的应用三-----------从Excel文件中读取条形码
条形码的应用三------从Excel文件中读取条形码 介绍 上一篇文章,我向大家展示了生成多个条形码并存储到Excel文件中的一个方法.后来我又有了个想法:既然条码插入到excel中了,我可不可以从 ...
- 【jacob word】使用jacob,合并多个word为一个word文件
将几个word文件合并到一个word文件,使用注意点: 1.后面附项目运用的jar包jacob-1.9, 2.并且jacob运用中,需要将附件内的jacob.dll放到windows/system32 ...
- java:利用java的输入/输出流将一个文件的每一行+行号复制到一个新文件中去
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- Java将对象保存到文件中/从文件中读取对象
1.保存对象到文件中 Java语言只能将实现了Serializable接口的类的对象保存到文件中,利用如下方法即可: public static void writeObjectToFile(Obje ...
- 从PCD文件中读取点云数据
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=84 在本小节我们学习如何从PCD文件中读取点云数据. 代码 章例1文件夹中, ...
- 【Python】从文件中读取数据
从文件中读取数据 1.1 读取整个文件 要读取文件,需要一个包含几行文本的文件(文件PI_DESC.txt与file_reader.py在同一目录下) PI_DESC.txt 3.1415926535 ...
- Python自动化测试框架——数据驱动(从文件中读取)
学过编程的伙伴们都知道,数据不仅可以从代码中读取,还可以从文件中读取. 今天小编就简要的介绍一下从文件中读取数据,并应用到自动化测试中方法. 先来展示下接下来将要用到的文件在项目中的结构 从txt文件 ...
随机推荐
- 学习爬虫的day03 (通过代理去爬去数据)
代理的IP通过去网上找# -*- coding: utf-8 -*- import re import _thread from time import sleep, ctime from urlli ...
- Glance 镜像服务群集
#Glance 镜像服务群集 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html#4.Glance 镜像服务群集 ##. ...
- 调用支付宝第三方接口(沙箱环境) SpringMVC+Maven
一.蚂蚁金服开放平台的操作 网址:https://open.alipay.com/platform/home.htm 支付宝扫码登陆
- 【LintCode·容易】用栈模拟汉诺塔问题
用栈模拟汉诺塔问题 描述 在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如:任意一个盘子,其必须堆在比它大的盘子上面).同时, ...
- numpy中关于*和dot的区别
1.numpy乘法运算中"*"是数组元素逐个计算 >>> import numpy as np >>> a = np.array([[2,3], ...
- 算法训练 区间K大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- DIN(Deep Interest Network of CTR) [Paper笔记]
背景 经典MLP不能充分利用结构化数据,本文提出的DIN可以(1)使用兴趣分布代表用户多样化的兴趣(不同用户对不同商品有兴趣)(2)与attention机制一样,根据ad局部激活用户兴趣相关的兴趣(用 ...
- jQuery的$.ajax方法响应数据类型有哪几种?本质上原生ajax响应数据格式有哪几种,分别对应哪个属性?
jQuery的$.ajax方法响应数据类型有:xml.html.script.json.jsonp.text 本质上原生ajax响应数据格式只有2种:xml和text,分别对应xhr.response ...
- ABAP CDS Table Function介绍与示例
Core data services(以下简称CDS)可以指两样东西,一个是HANA CDS,一个是ABAP CDS. 如我们所知,HANA CDS只支持HANA数据库,ABAP CDS理论上支持多种 ...
- java学习笔记之System类
System类常用总结 System类概述 java.lang.System类,系统属性信息工具类 常用静态方法: 1. public static long currentTimeMillis() ...