ooxml

Check-in [e06fcddeb0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Turns out, that creating the zip (at least as it currently done with vfs) eats up some time. Removed the need for vfs (only for writing!), now the zip is created with core on-board means. This reduces the time per cell needed for writing to 2/3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | populationspeed
Files: files | file ages | folders
SHA3-256: e06fcddeb0b9480b0cbeb9a06385927fd6bf2f03350d65d07598f07d65ac8a78
User & Date: rolf 2019-08-14 15:52:48
Context
2019-08-14
21:29
Added credits. Editorial clean-up. Removed the for this now not anymore used helper proc ::ooxml::Zip*. check-in: 43be3b2012 user: rolf tags: populationspeed
15:52
Turns out, that creating the zip (at least as it currently done with vfs) eats up some time. Removed the need for vfs (only for writing!), now the zip is created with core on-board means. This reduces the time per cell needed for writing to 2/3. check-in: e06fcddeb0 user: rolf tags: populationspeed
2019-08-13
21:10
Reworked the option parsing of the cell method for speed. check-in: 6c6aa2f98f user: rolf tags: populationspeed
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ooxml.tcl.

457
458
459
460
461
462
463











































































464
465
466
467
468
469
470
....
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
  # zh - Chinese - 中文 (Zhōngwén), 汉语, 漢語
  msgcat::mcset zh LANGUAGE \u4e2d\u6587
  msgcat::mcset zh Book \u5de5\u4f5c\u7c3f
  msgcat::mcset zh Worksheets \u5de5\u4f5c\u8868
  msgcat::mcset zh Sheet \u5de5\u4f5c\u8868
}













































































proc ::ooxml::Default { name value } {
  variable defaults

  switch -- $name {
    path {
      set defaults($name) [string trim $value]
................................................................................
    set file [string trim $file]
    if {$file eq {}} {
      set file {spreadsheetml.xlsx}
    }
    if {[file extension $file] ne {.xlsx}} {
      append file {.xlsx}
    }
    set path [file dirname $file]
    set uid [format xl_%X [clock microseconds]]
    set filesToZip {}
    foreach {tag doc} [array get obj doc,*] {
      lappend filesToZip [set docname [lindex [split $tag ,] 1]]
      set xmlfile [file join $path $uid $docname]
      file mkdir [file dirname $xmlfile]
      if {![catch {open $xmlfile w} fd]} {
	fconfigure $fd -encoding utf-8
	#puts $fd "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
	puts $fd [[$doc documentElement] asXML -indent $obj(indent) -xmlDeclaration 1 -encString [string toupper $obj(encoding)]]
	close $fd
	$doc delete
      }
    }
    set pwd [pwd]
    cd [file join $path $uid]
    if {$path eq {.}} {
      set file [file join .. $file]
    }
    ::ooxml::Zip $file . $filesToZip
    cd $pwd
    if {!$opts(holdcontainerdirectory)} {
      file delete -force [file join $path $uid]
    }
    return 0
  }
}


#
# ooxml::tablelist_to_xl







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
....
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217

3218
3219
3220
3221
3222
3223
3224
  # zh - Chinese - 中文 (Zhōngwén), 汉语, 漢語
  msgcat::mcset zh LANGUAGE \u4e2d\u6587
  msgcat::mcset zh Book \u5de5\u4f5c\u7c3f
  msgcat::mcset zh Worksheets \u5de5\u4f5c\u8868
  msgcat::mcset zh Sheet \u5de5\u4f5c\u8868
}

# ooxml::timet_to_dos
#
#        Convert a unix timestamp into a DOS timestamp for ZIP times.
#
#   DOS timestamps are 32 bits split into bit regions as follows:
#                  24                16                 8                 0
#   +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
#   |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s|
#   +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
#
  proc ::timet_to_dos {time_t} {
    set s [clock format $time_t -format {%Y %m %e %k %M %S}]
    scan $s {%d %d %d %d %d %d} year month day hour min sec
    expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) 
          | ($hour << 11) | ($min << 5) | ($sec >> 1)}
  }

  # ooxml::add_str_to_archive --
  #
  #        Add a string as a single file with string as content with
  #        argument path to a zip archive. The zipchan channel should
  #        already be open and binary. The return value is the central
  #        directory record that will need to be used when finalizing
  #        the zip archive.
  #

proc ::ooxml::add_str_to_archive {zipchan path data {comment ""}} {
  set mtime [timet_to_dos [clock seconds]]
  set utfpath [encoding convertto utf-8 $path]
  set utfcomment [encoding convertto utf-8 $comment]
  set flags [expr {(1<<11)}] ;# utf-8 comment and path
  set method 0               ;# store 0, deflate 8
  set attr 0                 ;# text or binary (default binary)
  set version 20             ;# minumum version req'd to extract
  set extra ""
  set crc 0
  set size 0
  set csize 0
  set seekable [expr {[tell $zipchan] != -1}]
  set attrex 0x81b60020  ;# 0o100666 (-rw-rw-rw-)
  
  set utfdata [encoding convertto utf-8 $data]
  set size [string length $utfdata]
  
  set offset [tell $zipchan]
  set local [binary format a4sssiiiiss PK\03\04 \
                 $version $flags $method $mtime $crc $csize $size \
                 [string length $utfpath] [string length $extra]]
  append local $utfpath $extra
  puts -nonewline $zipchan $local
  
  set crc [::zlib crc32 $utfdata]
  set cdata [::zlib deflate $utfdata]
  if {[string length $cdata] < $size} {
    set method 8
    set utfdata $cdata
  }
  set csize [string length $utfdata]
  puts -nonewline $zipchan $utfdata

  # update the header
  set local [binary format a4sssiiii PK\03\04 \
                 $version $flags $method $mtime $crc $csize $size]
  set current [tell $zipchan]
  seek $zipchan $offset
  puts -nonewline $zipchan $local
  seek $zipchan $current
  
  set hdr [binary format a4ssssiiiisssssii PK\01\02 0x0317 \
               $version $flags $method $mtime $crc $csize $size \
               [string length $utfpath] [string length $extra]\
               [string length $utfcomment] 0 $attr $attrex $offset]
  append hdr $utfpath $extra $utfcomment
  return $hdr
}

proc ::ooxml::Default { name value } {
  variable defaults

  switch -- $name {
    path {
      set defaults($name) [string trim $value]
................................................................................
    set file [string trim $file]
    if {$file eq {}} {
      set file {spreadsheetml.xlsx}
    }
    if {[file extension $file] ne {.xlsx}} {
      append file {.xlsx}
    }
    if {[catch {set zf [open $file w]}]} {
      error "Unable to write $file"
    }
    fconfigure $zf \
        -encoding    binary \
        -translation binary \
        -eofchar     {}
    set count 0
    set cd ""
    foreach {tag doc} [array get obj doc,*] {
      append cd [::ooxml::add_str_to_archive $zf \
                     [lindex [split $tag ,] 1] \
                     [[$doc documentElement] asXML \
                          -indent $obj(indent) -xmlDeclaration 1 \
                          -encString [string toupper $obj(encoding)]]]
      incr count
      $doc delete
    }
    set cdoffset [tell $zf]
    set endrec [binary format a4ssssiis PK\05\06 0 0 \
                    $count $count [string length $cd] $cdoffset 0]
    puts -nonewline $zf $cd
    puts -nonewline $zf $endrec
    close $zf

    return 0
  }
}


#
# ooxml::tablelist_to_xl