zghbssjzzy
zghbssjzzy
采纳率0%
2016-03-06 12:20

求助,写一个VFP直接读写EXCEL二进制文件的程序,求教EXCEL文件格式。

在用VFP读写EXCEL文件数据时,当遇到非标准的EXCEL文件或高版本的EXCEL文件,VFP就会出错。这时通过调用第三方软件转换以后就可以使用了。但是在WINDOWS 7以上,系统会阻止VFP调用第三方软件。只有打开EXCEL文件直接读写数据了。
    在网上查了一些资料,但是对EXCEL文件的结构和读写的方法还不明白,求助高人指点一下。目前只能读取和解析文件头,试着读出了扇区列表,目录读取不正确,其他还不会……。
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

9条回答

  • caozhy 从今以后生命中的每一秒都属于我爱的人 5年前

    excel文件的格式极其复杂,特别是通过ole方式嵌入别的文件格式。如果你希望自己从底层开始来解析excel,那么工作量之大超过你的想象。

    点赞 1 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    *火车文件系统
    *2016-3-10
    *zhangyi
    *测试通过
    *说明:目录没有按树形排序,今天累了,明天再说吧。


    RETURN 火车()
    PROCEDURE 火车
    PRIVATE ALL
    ?PROG()

    系统设置()
    读入表结构()
    生成表名称()
    新建空表()
    
    初始文件([1.XLS])
    检测文件()
    打开文件()
    是否火车()
    读入文件()
    解析车头()
    解析柜车()
    解析卡车()
    解析车位()
    解析小车专列()
    解析小车()
    解析目录专列()
    解析目录()
    关闭文件()
    

    ENDPROC


    *


    PROCEDURE 系统设置
    PRIVATE ALL
    ?PROG()

    ON SHUTDOWN QUIT
    
    SET TALK OFF
    SET SAFE OFF
    
    SET ANSI ON 
    SET EXACT ON 
    SET ENGINEBEHAVIOR 70
    
    CLOSE ALL
    CLEAR ALL
    CLEAR
    

    ENDPROC


    *


    PROCEDURE 读入表结构
    PRIVATE ALL
    ?PROG()

    CREATE CURSOR 表结构 (;
        结构名称 V (20),;
        字段名称 V (40),;
        字段类型 V (1) ,;
        字段长度 I ,;
        字段小数 I ,;
        取数方法 V (10) ,;
        开始位置 I ,;
        数据长度 I ,;
        计算公式 V (40) ,;
        字段顺序 I ;
    )
    
    ERR=.F.
    TRY
        APPEND FROM 表结构 XLS ;
        FOR 结构名称#[结构名称] ;
        AND NOT EMPTY(结构名称)
    CATCH
        \ERROF:打开“表结构.XLS”时出错,
        \请查检文件是否正在打开,
        \或者已经删除。
        ERR=.T.
    ENDTRY
    IF ERR
        RETURN TO MASTER
    ENDIF
    
    UPDATE 表结构 SET 字段顺序=RECNO()
    

    ENDPROC


    *


    PROCEDURE 生成表名称
    PRIVATE ALL
    ?PROG()

    CREATE CURSOR 表名称 (结构名称 V (20))
    
    INSERT INTO 表名称 ;
    SELECT DIST 结构名称 ;
    FROM 表结构 ;
    ORDER BY 字段顺序
    

    ENDPROC


    *


    PROCEDURE 新建空表
    PRIVATE ALL
    ?PROG()

    SELECT 表名称
    SCAN
    REC=RECNO()
        当前表名=结构名称
        新表(当前表名)
    SELECT 表名称
    GO REC
    ENDSCAN
    

    ENDPROC


    *


    PROCEDURE 新表(当前表名)
    PRIVATE ALL
    SELECT ;
    字段名称,;
    字段类型,;
    字段长度,;
    字段小数 ;
    FROM 表结构 ;
    WHERE 结构名称=当前表名 ;
    INTO ARRAY AAA

    CREATE CURSOR (当前表名) FROM ARRAY AAA
    

    ENDPROC


    *


    PROCEDURE 复制(当前表样,当前表名)
    PRIVATE ALL
    AFIELD(AAA,当前表样)
    CREATE CURSOR (当前表名) FROM ARRAY AAA
    ENDPROC


    *


    PROCEDURE 清空(当前表名)
    PRIVATE ALL
    ZAP IN (当前表名)
    ENDPROC


    *


    PROCEDURE 关闭(当前表名)
    PRIVATE ALL
    USE IN (当前表名)
    ENDPROC


    *


    PROCEDURE 新行(当前表名)
    PRIVATE ALL
    APPEND BLANK IN (当前表名)
    ENDPROC


    *


    PROCEDURE UInt8(SS,NN)
    PRIVATE ALL
    S1=SUBSTR(SS,NN,1)
    RETURN CTOBIN(S1,[1RS])
    ENDPROC


    *


    PROCEDURE UInt16(SS,NN)
    PRIVATE ALL
    S1=SUBSTR(SS,NN,2)
    RETURN CTOBIN(S1,[2RS])
    ENDPROC


    *


    PROCEDURE UInt32(SS,NN)
    PRIVATE ALL
    S1=SUBSTR(SS,NN,4)
    RETURN CTOBIN(S1,[4RS])
    ENDPROC


    *


    PROCEDURE UCHAR(SS,NN,LL)
    PRIVATE ALL
    RETURN SUBSTR(SS,NN,LL)
    ENDPROC


    *


    PROCEDURE WCHAR(SS,NN,LL)
    PRIVATE ALL
    RETURN STRCONV(SUBSTR(SS,NN,LL),6)
    ENDPROC


    *


    PROCEDURE 初始文件(当前文件)
    PRIVATE ALL
    ?PROG()
    INSERT INTO 文件 (文件名) VALUE(当前文件)
    ENDPROC


    *


    PROCEDURE 检测文件
    PRIVATE ALL
    ?PROG()
    UPDATE 文件 SET 发现文件=FILE(文件名)
    ENDPROC


    *


    PROCEDURE 打开文件
    PRIVATE ALL
    ?PROG()
    UPDATE 文件 SET 文件号=-1
    UPDATE 文件 SET 文件号=FOPEN(文件名,12) WHERE 发现文件
    UPDATE 文件 SET 打开文件=(文件号>-1)
    ENDPROC


    *


    PROCEDURE 关闭文件
    PRIVATE ALL
    ?PROG()
    UPDATE 文件 SET 关闭文件=FCLOSE(文件号) WHERE 打开文件
    ENDPROC


    *


    PROCEDURE 是否火车
    PRIVATE ALL
    ?PROG()
    UPDATE 文件 SET 指针位置=FSEEK(文件号, 0, 0)
    UPDATE 文件 SET 火车标志=FREAD(文件.文件号,8)
    UPDATE 文件 SET 指针位置=FSEEK(文件号, 0, 0)
    UPDATE 文件 SET 是火车=STRCONV(火车标志,15)=[D0CF11E0A1B11AE1]
    IF NOT 文件.是火车
    \不是火车文件
    关闭文件()
    RETURN TO MASTER
    ENDIF
    ENDPROC


    *


    PROCEDURE 读入文件
    PRIVATE ALL
    ?PROG()
    当前表名=[车箱]
    清空(当前表名)
    FSEEK(文件.文件号, 0, 0)
    DO WHILE NOT FEOF(文件.文件号)
    INSERT INTO (当前表名) VALUE (FREAD(文件.文件号,512))
    ENDDO
    FSEEK(文件.文件号, 0, 0)
    ENDPROC


    *


    PROCEDURE 定位车箱(当前编号)
    PRIVATE ALL
    GO 当前编号+2 IN 车箱
    ENDPROC


    *


    PROCEDURE 定位车位(当前编号)
    PRIVATE ALL
    GO 当前编号+1 IN 车位
    ENDPROC


    *


    PROCEDURE 解析车箱(当前偏移,当前结构,当前表名)
    PRIVATE ALL
    SELECT 表结构
    SCAN FOR 结构名称=当前结构
    REC=RECNO()

        当前字段=字段名称
        当前方法=取数方法
        当前位置=开始位置
        当前长度=数据长度
        当前公式=计算公式
    
        DO CASE
        CASE 当前方法=[UCHAR]
            当前数据 = UCHAR(车箱.W,当前偏移+当前位置,当前长度) 
        CASE 当前方法=[WCHAR]
            当前数据 = WCHAR(车箱.W,当前偏移+当前位置,当前长度) 
        CASE 当前方法=[UINT8]
            当前数据 = UINT8(车箱.W,当前偏移+当前位置) 
        CASE 当前方法=[UINT16]
            当前数据 = UINT16(车箱.W,当前偏移+当前位置) 
        CASE 当前方法=[UINT32]
            当前数据 = UINT32(车箱.W,当前偏移+当前位置) 
        CASE NOT EMPTY(当前公式)
            SELECT (当前表名)
            当前数据 = EVAL(当前公式)
        OTHERWISE 
            LOOP
        ENDCASE
    
        TRY
            REPLACE IN (当前表名) &当前字段 WITH 当前数据
        CATCH
            \ERROR
        ENDTRY
    
    SELECT 表结构
    GO REC
    ENDSCAN
    

    ENDPROC


    *


    PROCEDURE 解析车头
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前车箱=-1
    当前偏移=0
    当前表名=[车头]
    
    **********
    *清空数据
    **********
    清空(当前表名)
    
    **********
    *新建记录
    **********
    新行(当前表名)
    
    **********
    *定位车箱
    **********
    定位车箱(当前车箱)
    
    **********
    *解析车头
    **********
    解析车箱(当前偏移,当前表名,当前表名)
    

    ENDPROC


    *


    PROCEDURE 解析柜车
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前补车=车头.补车入口
    当前个数=车头.补车个数
    当前表名=[柜车]
    当前偏移=509
    
    **********
    *初始化
    **********
    清空(当前表名)
    
    **********
    *车头
    **********
    APPEND BLANK IN (当前表名)
    REPL IN (当前表名) 入口 WITH -1
    REPL IN (当前表名) 偏移 WITH 77
    REPL IN (当前表名) 个数 WITH 109
    REPL IN (当前表名) 车链 WITH 当前补车
    
    **********
    *补车
    **********
    FOR 当前循环=1 TO 当前个数
    
        当前车箱=当前补车
    
        IF 当前车箱<0
            EXIT
        ENDIF
    
        定位车箱(当前车箱)
    
        当前补车=UINT32(车箱.W,当前偏移)
    
        APPEND BLANK IN (当前表名)
        REPL IN (当前表名) 入口 WITH 当前车箱
        REPL IN (当前表名) 偏移 WITH 1
        REPL IN (当前表名) 个数 WITH 127
        REPL IN (当前表名) 车链 WITH 当前补车
    ENDFOR
    

    ENDPROC


    *


    PROCEDURE 解析卡车
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前表名=[卡车]
    
    **********
    *初始化
    **********
    清空(当前表名)
    
    **********
    *扫描柜车
    **********
    SELECT 柜车
    SCAN
    REC=RECNO()
    
        **********
        *当前变量
        **********
        当前车箱=入口
        当前偏移=偏移
        当前个数=个数
    
        **********
        *无效车箱
        **********
        IF 当前车箱<-1
            LOOP
        ENDIF
    
        **********
        *定位柜车
        **********
        定位车箱(当前车箱)
    
        **********
        *读出卡车
        **********
        FOR 当前循环=1 TO 当前个数
    
            当前位置=(当前循环-1)*4
            当前卡车=UINT32(车箱.W,当前偏移+当前位置)
            APPEND BLANK IN (当前表名)
            REPL IN (当前表名) 入口 WITH 当前卡车
    
        ENDFOR
    
    SELECT 柜车
    GO REC
    ENDSCAN
    

    ENDPROC


    *车位状态:
    *-1 空闲车位
    *-2 车链结束
    *-3 卡车专用
    *-4 柜车专用

    • 0 无效数据
      *>0 车链使用,是下个车箱编号


      PROCEDURE 解析车位
      PRIVATE ALL
      ?PROG()


      *当前变量


      当前表名=[车位]


      *初始化


      清空(当前表名)


      *扫描卡车


      SELECT 卡车
      SCAN
      REC=RECNO()

      **********
      *当前变量
      **********
      当前车箱=入口
      当前偏移=1
      当前个数=128
      
      **********
      *无效车箱
      **********
      IF 当前车箱<0
          LOOP
      ENDIF
      
      **********
      *定位卡车
      **********
      定位车箱(当前车箱)
      
      **********
      *读出车位
      **********
      FOR 当前循环=1 TO 当前个数
      
          当前位置=(当前循环-1)*4
          当前状态=UINT32(车箱.W,当前偏移+当前位置)
          APPEND BLANK IN (当前表名)
          REPL IN (当前表名) 状态 WITH 当前状态
      
      ENDFOR
      

      SELECT 卡车
      GO REC
      ENDSCAN

    ENDPROC


    *


    PROCEDURE 解析小车专列
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前车箱=车头.小车入口
    当前个数=车头.小车个数
    当前表名=[小车专列]
    
    **********
    *初始化
    **********
    清空(当前表名)
    
    **********
    *扫描车位
    **********
    FOR 当前循环=1 TO 当前个数
    
        **********
        *无效车箱
        **********
        IF 当前车箱<0
            LOOP
        ENDIF
    
        **********
        *保存数据
        **********
        APPEND BLANK IN (当前表名)
        REPL IN (当前表名) 入口 WITH 当前车箱
    
        **********
        *定位车位
        **********
        定位车位(当前车箱)
    
        **********
        *读出状态
        **********
        当前状态=车位.状态
    
        **********
        *车位状态
        **********
        DO CASE
        CASE 当前状态=-1 &&空闲车位
        CASE 当前状态=-2 &&车链结束
        CASE 当前状态=-3 &&卡车专用
        CASE 当前状态=-4 &&柜车专用
        CASE 当前状态=0  &&无效数据
        CASE 当前状态>0  &&车链使用,是下个车箱编号
            当前车箱=当前状态
        ENDCASE
    
    ENDFOR
    

    ENDPROC


    *1分8


    PROCEDURE 解析小车
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前表名=[小车]
    当前编号=0
    
    **********
    *初始化
    **********
    清空(当前表名)
    
    **********
    *扫描小车专列
    **********
    SELECT 小车专列
    SCAN
    REC=RECNO()
    
        当前入口=入口
    
        FOR 当前位置=0 TO 7
    
            APPEND BLANK IN (当前表名)
            REPL IN (当前表名) 入口 WITH 当前入口
            REPL IN (当前表名) 位置 WITH 当前位置
            REPL IN (当前表名) 编号 WITH 当前编号
    
            当前编号=当前编号+1
        ENDFOR
    
    SELECT 小车专列
    GO REC
    ENDSCAN
    

    ENDPROC


    *


    PROCEDURE 解析目录专列
    PRIVATE ALL
    ?PROG()

    **********
    *当前变量
    **********
    当前车箱=车头.目录入口
    当前表名=[目录专列]
    
    **********
    *初始化
    **********
    清空(当前表名)
    
    **********
    *扫描车位
    **********
    DO WHILE 当前车箱>0 AND NOT EOF([车位])
    
        **********
        *保存数据
        **********
        APPEND BLANK IN (当前表名)
        REPL IN (当前表名) 入口 WITH 当前车箱
    
        **********
        *定位车位
        **********
        定位车位(当前车箱)
    
        **********
        *车位状态
        **********
        当前车箱=车位.状态
    
    ENDDO
    

    ENDPROC


    *目录类型:

    • 0 Invalid ,无效数据
    • 1 Storage ,目录
    • 2 Stream ,文件
    • 3 LockBytes,锁定字节
    • 4 Property ,属性
    • 5 Root ,根目录


      PROCEDURE 解析目录
      PRIVATE ALL
      ?PROG()


      *当前变量


      当前结构=[目录]
      当前表名=[目录]
      当前编号=0


      *扫描目录专列


      SELECT 目录专列
      SCAN
      REC=RECNO()

      **********
      *当前变量
      **********
      当前车箱=入口
      
      **********
      *定位目录车箱
      **********
      定位车箱(当前车箱)
      
      **********
      *1分4
      **********
      FOR 当前位置=0 TO 3
      
          当前偏移=当前位置*128
      
          APPEND BLANK IN (当前表名)
          REPL IN (当前表名) 车箱 WITH 当前车箱
          REPL IN (当前表名) 位置 WITH 当前位置
          REPL IN (当前表名) 编号 WITH 当前编号
      
          解析车箱(当前偏移,当前结构,当前表名)
      
          当前编号=当前编号+1
      
      ENDFOR
      

      SELECT 目录专列
      GO REC
      ENDSCAN

    ENDPROC


    *END OF ALL


    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    今天重新修正了一下,下图是“火车文件系统”数据结构:
    图片说明

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    (八)虚拟小火车
    有些“货物”“容量”很小,如果给它分配“专列”,就连一个“车箱”都很浪费。为了节省空间,
    我们把一个“车箱”切成8段,每一段当作一个“小车箱”用,把它称作“小车箱”。
    这样以来,我们就可以虚拟出一列“小火车”了。

    但是,并非每个EXCEL文件必须有“小火车”,需要的时修改才会有。
    我们规定,当“货物容量”小于4096字节时,才会在“小火车”中,生成一个“小专列”,用来保存货物。
    当“货物容量”大于等于4096字节时,直接保存在“货物专列”中。

    “小火车”的管理,类似“火车”的管理。
    首先虚拟一列“小火车”,
    然后把“小火车”切成“小车箱”,
    每个“小车箱”有一个“小车箱编号”从0-N,
    每个“小车箱”对应一个“小车位”,
    “小车位”放到“小车位车箱”中,然后形成“小车位专列”,
    “小车位车箱”由“小车本”管理,
    “小车本”放到“小车本车箱”中,然后形成“小车本专列”。

    (九)特殊专列的生成(正在学习中……)
    1“车本专列”的生成
    2“车位专列”的生成
    3“小车本专列”的生成
    4“小车位专列”的生成
    5“小火车”的生成
    6“虚拟小专列”的生成

    (十)车头结构

    (十一)目录专列和目录树

    (十二)垃圾数据

    三、EXCEL文件解析

    四、测试程序

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    (五)车箱用法
    使用原则:“先进先出”。
    比如,有一批“货物”来了(对于货物是按批次管理的),需要存放到“车箱”里。
    就从“车位”开头找起,看看哪节车箱空闲,找到后就把货物放到那里。
    如果一个“车箱”放不下,就往后再找一个“空闲车箱”,直到货物放完。
    如果找完“车位”,也没有“空闲车箱”可用,则先增加一个“车位专用”车箱,会多出128个空闲车位,
    然后增加一个“车箱”,往里面放“货物”即可。
    如果“车本”也用完了,则应该先增加一个“车本专用”车箱,然后再增加一个“车位专用”车箱,
    然后再增加一个“货物使用”车箱。即可。

    (六)货物管理
    在管理“货物”时,我们把“货物”分成一批一批的。
    每批货物自成一体,并且有一个不能重名的“名称”。
    货物“顺序”地放到“车箱”中,“顺序”地取出来。
    每批货物都用一个“虚拟专列”,来存放货物。

    (七)虚拟专列
    当给定一个“车箱编号”,我们就可以在“火车”中找到这个“车箱”:
    车箱记录号 = 车箱编号+2
    当把一个“车箱”和下个“车箱”用“车链”栓在一起,这样串下去,直到没有“车链”为止。这样就得到一串“车箱”,叫作“虚拟专列”。
    “车链”的信息保存在“车位”数据表中。
    “虚拟专列”是为了给货物管理提供方便的,所以“虚拟专列”主要是“货物专列”。
    “货物专列”是用来存储货物的基本手段。目录、文件、属性、摘要、常量、垃圾等各种货物,在存储时,
    都要先分得一个“货物专列”,然后将“货物”存到“货物专列”中。
    “货物专列”的第一个“车箱编号”叫“专列入口”。
    当给定一个“专列入口”后,根据上面方法,就可以找到一个“货物专列”。

    有几个特殊专列,其管理方法与上不同:
    “车位专用”车箱,形成一个“车位专列”,
    “车本专用”车箱,形成一个“车本专列”,

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    (三)车箱位置
    生活中,火车进站后,就停靠到站台上。每个“车箱”对应一个“车位”。
    相应地,EXCEL文件被切段,存到“车箱”数据表中后。每条“记录”也对应一个“车位”。
    所有“车位”的信息,保存到“车位”数据表中。“车位信息”就是“车箱状态”。
    “车箱状态”,是一个数字,4字节长。可以是以下数值:
    -1,空闲位置,没有车箱。
    -2,车链结束
    -3,车位专用
    -4,车本专用
    [0-N],货物使用,是下个车箱编号
    “车位编号”和“车位记录号”的关系是:车位编号+1 = 车位记录号
    “车位”个数可能多于“车箱”个数。

    (四)车位管理
    “车位信息”装在“车位专用”车箱中。一节车箱有128个“车位信息”。
    随着“货物”的增多,“车箱”也增多。当“车位”不够时,就增加一节“车位专用”车箱,就会多出128个“车位”来。这样下去,“车位专用”车箱也会越来越多。
    为管理“车位专用”车箱,用一个“账本”记录每个“车位专用”车箱的“车箱编号”,把它称作“车本”。存放在“车头”里。
    由于容量限制,车头里的“车本”,只能记录109个“车位专用”车箱的“车箱编号”。
    如果没有新的车位可能,则这个EXCEL文件最多只能保存:109 * 128=13952个车位,对应13952个车箱,
    每个车箱512字节,EXCEL文件总容量=7143424字节,约6.8125M数据。
    为了增加更多“车位”,就必须增加“车本”的容量。只能在“车头”后面,接上一个“车箱”,专门保存“车本”的内容。
    我们把这种车箱称做“车本专用”车箱。其里面记录的是“车位专用”车箱的“车箱编号”。
    并把其最后一个号码留下,用于保存下一个“车本专用”车箱的“车箱编号”。这样“车本专用”车箱就可以无限地增加了。
    在一个“车本专用”就车箱中,能保存128-1=127个“车位专用”车箱的“车箱编号”。

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    一、什么是“火车文件系统”
    我觉得把EXCEL比喻成一列火车很形象,用实物做比喻,更容易理解抽象概念。“火车文件系统”描述了一个文件内部如何组织管理嵌入文件的,与微软的OFFICE“复合文档”体系相似,跟《劳拉文件系统》差不多。其实都是对“复合文档”的管理,做的事情是一回事,管理方法、手段差不多,达到的结果相似,但是说法各异。

    二、把EXCEL文件变成“一列火车”
    (一)一列火车
    把一个EXCEL文件,切成一段一段的,每段512字节,放到一个数据表中,该表名称叫做“车箱”。
    所有“车箱”构成一列“火车”。第一条记录叫“车头”,剩下的记录都叫“车箱”。
    为管理方便,每个车箱有个“车箱编号”,从0-N。车头也有“车箱编号”,是-1。
    “车箱编号”和“车箱记录号”的关系是:车箱编号+2 = 车箱记录号
    因此,用“火车文件系统”保存的文件,大小一定是512字节的整数倍。

    (二)车箱用途
    这列火车不是用来开的,我们把它摆在那,用来装“货物”。
    车头,用来存放控制信息。
    车箱,用来装货物。货物就是各种数据,可能是“工作簿”“工作表”“OLE物件”等等。
    货物多时,就增加车箱,货物少时,就去掉车箱,总之车箱够用,但也不浪费(空着不用)。

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    我自己摸索着,一点点地做吧。求路过的高人指点一二。

    【火车文件系统】

    真是可惜,微软不再升级VFP9软件了。这是一个很好用的数据库软件,我一直在用它写小程序,管理一些数据。平时经常遇到需要读写EXCEL文件的情况,但是因VFP9处理EXCEL文件能力不足,有时需要借助第三方软件,比如EXCELRW.DLL、LIBXL.DLL等,或者通过COM方式调用OFFICE或WPS来操作EXCEL文件,但是经常遇到问题。

    有一天突发奇想,想直接用VFP读写EXCEL文件,那不就省事了吗。从网上查了一些资料,认真地学习,可是打击实在太大了。这时我认识到:知识是多么深广啊,自己是多么乏力呀!经过一番努力,从混乱中理出一点点头绪,总结一下,以资继续努力。

    列举前辈的文章,以示尊敬:

    1、马丁.施瓦兹的《劳拉文件系统》(德国)原文:《LAOLA file system》网址:
    https://stuff.mit.edu/afs/athena/astaff/project/mimeutils/OldFiles/src/laola/guide.html
    2、大魔王的《Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析》(中国)网址:
    http://www.cnblogs.com/mayswind/archive/2013/03/17/2962205.html
    3、Agstick的《复合文档文件格式研究》(中国)网址:
    http://club.excelhome.net/thread-227502-1-1.html
    4、July的《教你透彻了解红黑树》(中国)网址:
    http://blog.csdn.net/v_JULY_v/article/details/6105630

    点赞 评论 复制链接分享
  • zghbssjzzy zghbssjzzy 5年前

    其实只需要基本的读写功能就行了。我从网上看了一个LAOLA FILE SYSTEM的介绍,看懂了一点点,现在正在解析目录。但是对目录的管理机制不清楚。全是外国人的资料,看不懂呀。希望已经走过来的高人指点一下呀。

    点赞 评论 复制链接分享

相关推荐