zoukankan      html  css  js  c++  java
  • 从一个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>
    View Code

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

    段落标签: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(1), 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 = 0, len = lineData.size(); i != len; ++i)
                    {
                        if(lineData[i].m_vSpan && !data.isEmpty())        //表格是否存在垂直合并的情况
                            lineData[i].m_value = data.last().at(i);
                        
                        for(int j = 0; 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();
        }
    }
    源文件
  • 相关阅读:
    Spring源码情操陶冶-自定义节点的解析
    SpringMVC源码情操陶冶-DispatcherServlet
    springcloud config配置读取优先级
    Maven-常用插件
    springcloud情操陶冶-springcloud config server(三)
    springcloud情操陶冶-springcloud config server(二)
    springcloud情操陶冶-bootstrapContext(三)
    springcloud情操陶冶-springcloud config server(一)
    springcloud情操陶冶-bootstrapContext(二)
    springcloud情操陶冶-bootstrapContext(一)
  • 原文地址:https://www.cnblogs.com/zhugaopeng/p/7118352.html
Copyright © 2011-2022 走看看