Tabulator 列数を動的に変える

 

 

 

画像のサイズや列数を変えてTabulatorでサムネイル表示させる為、列数、列幅を動的設定してみました。

< コード例 >

ローカルストレージにあるユーザー設定読込


// == ユーザー設定読込 == //
    const envmap = new ConfigPhoto().readLSMap()
    const w = envmap["thumbwidth"]    // 列幅
    const colcnt = envmap["colcnt"]   // 列数

// サムネイル列 //
let COLUMNS = [
  {title: `検索結果 X <span id="cnt_photo"></span>
           `,
    columns: []
  }
]

// ++ 設定列数分の列を動的追加 ++ //
for (let j = 0; j < colcnt; j++) {

  // 画像列 //
  const coltmp = {
    title: "", field: "COL" + j, width: w, hozAlign: "center",
    formatter: cellFormat, contextMenu: cellContextMenu
  }
  COLUMNS[0]["columns"].push(coltmp);

  // 非表示列 //
  COLUMNS[0]["columns"].push({field: "COL" + j + "_COL_AVG", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_URL", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_PHOTOID", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_TITLE", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_PHOTOGRAPHER", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_POS", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_IDX", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_CATEG_KANJI", visible: false})
  COLUMNS[0]["columns"].push({field: "COL" + j + "_URL_ORIGINAL", visible: false})

}

// 列設定 //
const tablerows = this.getArrangedColumnsDataColCnt(data, colcnt)

// ++ Tabulator ++ //
let table = new Tabulator("#table_photos", {
  columns: COLUMNS,
  data: tablerows,
  //placeholder: '見つかりませんでした',

  //layout: 'fitColumns',
  //layout:"fitData",
  layout: "fitDataTable",

  rowHeight: Math.round(w * 3 / 4),
  headerVisible: false

})

列設定メソッド


  /**
   * テーブル用サムネイル列設定
   * 列数指定用 使用
   * 
   * @param {type} data 応答データ
   * @param {type} colcnt 列数
   * @returns {Array|Photos.getArrangedColumnsData.resdatas}
   */
  getArrangedColumnsDataColCnt(data, colcnt) {

// == ユーザー設定幅読込 == //
 const w = new ConfigPhoto().readLSMap()["thumbwidth"]

  let resdatas = []
  let row = {}
  data.forEach((tmp, i) => {

    const mod = i % colcnt;

    row["COL" + mod] = w <= 250 ? tmp["URL_SMALL"] : tmp["URL_MEDIUM"]
    row["COL" + mod + "_COL_AVG"] = tmp["COL_AVG"]
    row["COL" + mod + "_URL"] = tmp["URL"]
    row["COL" + mod + "_PHOTOID"] = tmp["PHOTOID"]
    row["COL" + mod + "_TITLE"] = tmp["TITLE"]
    row["COL" + mod + "_PHOTOGRAPHER"] = tmp["PHOTOGRAPHER"]
    row["COL" + mod + "_POS"] = tmp["POS"]
    row["COL" + mod + "_IDX"] = tmp["IDX"]
    row["COL" + mod + "_NM_CATEG_KANJI"] = tmp["NM_CATEG_KANJI"]
    row["COL" + mod + "_URL_ORIGINAL"] = tmp["URL_ORIGINAL"]

    if (i === data.length - 1) {
      resdatas.push(row)
    }

    else if (mod === colcnt - 1) {
      resdatas.push(row)
      row = {}
    }



  })
  return resdatas

}

< 画面例 >

幅250px 5列

幅100px 12列

幅60px 16列

Tabulator initialSort とソート内容表示

 

 

 

< コード例 >


// ロード時既定ソート列 リクエストパラメータはsortでMapのList //
      initialSort: [
        {column: "NM_FILE", dir: "asc"}, //sort by this first
                //{column:"TM_UPDATE", dir:"desc"}//then sort by this second
      ],

カラムの1行目にspanをセット


<span id="sorttxt" class="ml-2">ソート列:ソート順</span>

ソート後のイベント


  /**
     * ソート表示テキスト
     * @param {type} clms
     * @param {type} sorters
     * @returns {String}
     */
    const sortstsstr = (clms, sorters) => {
      
      let clmmap = {}
      clms.forEach(tmp => clmmap[tmp.field] = tmp.title)
      
      let res = ""
      sorters.forEach(st => 
        res += clmmap[st["field"]] + (st.dir === "asc" ? ":小さい順 " : "大きい順 ")
      )
      return res
      
    }
    
    // @@ ソートが完了した時 @@ //
    table.on("dataSorted", function (sorters, rows) {
      //sorters - array of the sorters currently applied
      //rows - array of row components in their new order
      
   
      // 初回ロード時も呼ばれる //
      $("#sorttxt").text(sortstsstr(COLUMNS[0]["columns"], sorters))
      
      
    });

< 画面例 >

Tabulator AJaxリクエストと表示

 

 

 

Tabulatorのテーブルのデータとして、今まで大容量、多いレコードのデータを読み込む必要がなかった為、Ajaxでリクエストして受信したデータを一旦ローカルの配列にして表示させてましたが、
この度、大量のデータでページ毎に読み込む必要があって試してみました。Tabulatorのドキュメントの通りにしてます。

詳しくはこちら

< コード例 >

Javascriptクライアント


// ++ Tabulator ++ //
    let table = new Tabulator('#table_files', {
      columns: COLUMNS,

      // ロード時既定ソート列 リクエストパラメータはsortでMapのList //
      initialSort: [
        {column: "NM_FILE", dir: "asc"}, //sort by this first
                //{column:"TM_UPDATE", dir:"desc"}//then sort by this second
      ],
      
      // ソートモードはサーバー側 //
      sortMode: "remote",

      ajaxURL: url, //ajax URL
      
      // AJaxのリクエストパラメータ //
      ajaxParams: {
        years: years, folders: folders, exts: exts, fnm: fnm, isin: isin,
        ischart: isChartShow ? "1" : "0"
      },
      ajaxConfig: "POST",
      index: "id",

      ajaxRequesting: function (url, params) {
        return true
      },
	  
      // == レスポンスの処理 == //
      // dataのキーを返す応答 + jqGridのuserDataの処理 //
      ajaxResponse: function (url, params, response) {
        //url - the URL of the request
        //params - the parameters passed with the request
        //response - the JSON object returned in the body of the response.

        console.log(response)

        // === ここにテーブル以外の処理を入れる === //

        return response
      },
      		
      // ==== 省略 ==== //
      		
})

PHPサーバー
データ配列のキーはTabulatorがデフォルトで使う “data”にします。
レスポンスにTabulatorがデフォルトで使う “last_page” を加えます


<?php

// == リクエストパラメータ == //

// Tabulatorが送るページインデックスとレコード数 //
// ページと行数 //
$page = $_POST["page"] ? $_POST["page"] : $_GET["page"];
$size = $_POST["size"] ? $_POST["size"] : $_GET["size"];

// Tabulatorが送るソート列と方向 //
// ソート //
$sorts = $_POST["sort"] ? $_POST["sort"] : $_GET["sort"];

$sort_column = $sorts[0]["field"];
$sort_order = $sorts[0]["dir"];


// レスポンス配列 //
 $resp = array(
      "data" => $response_array_limited,
      "sql" => $sql_files,             // 実行SQL
      "last_page" => $last_page,       // <== Tabulatorが使うデフォルトページ数
      "totalcount" => $totalcount,     // 合計レコード数
      "tmcost" => $entm - $sttm,
      "total_file_size" => $total_file_size,
      
      "sorts" => $sorts
  );

  echo json_encode($resp, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES + JSON_NUMERIC_CHECK + JSON_UNESCAPED_LINE_TERMINATORS);


<?php

// SQL ソートとページング部分 //

ORDER BY
  ##SORT_COLUMN## ##SORT_ORDER##, NM_FOLDER ASC, NM_FILE ASC
LIMIT :STARTIDX, :PAGESIZE  

// ソートはSQL文を置換 //
$sql_files = str_replace("##SORT_COLUMN##", $sort_column, $sql_files);
$sql_files = str_replace("##SORT_ORDER##", $sort_order, $sql_files);

// ページングはパラメータを渡す //

// ページング用 //
$startidx = ($page - 1) * $size;
$endidx = $startidx + $size - 1;
$last_page = (int) ($totalcount / $size) + 1;

// 明細 パラメータセット 実行 //
$stmt = $dbh->prepare($sql_files);
$stmt->bindvalue(':STARTIDX', $param_startidx, PDO::PARAM_INT);
$stmt->bindvalue(':PAGESIZE', $param_size, PDO::PARAM_INT);
$stmt->execute();

PHP WordをHTML出力 docx_reader

GitHubのリンク

< コード例 >

docx_reader.phpを配置してincludeで読み込んで使います。


include('./docx_reader.php');


// == リクエストパラメータ == //
$filename = $_POST["filename"] ? $_POST["filename"] : $_GET["filename"];

if (!$filename) {
  $filename = "/path/filename.docx";
}

$doc = new Docx_reader();
$doc->setFile($filename);

if(!$doc->get_errors()) {
    $html = $doc->to_html();
    $plain_text = $doc->to_plain_text();

    echo $html;
} else {
    echo implode(', ',$doc->get_errors());
}
echo "\n";

PHP ExcelをHTML出力 excel2html

GitHubのリンク

< インストール >

composer でインストールします。

[????@????]# composer require tomk79/php-excel2html
Cannot load Zend OPcache - it was already loaded
No composer.json in current directory, do you want to use the one at /home/ApacheDoc/invfiles? [Y,n]? n
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? y
Info from https://repo.packagist.org: #StandWithUkraine
./composer.json has been created
Running composer update tomk79/php-excel2html
Loading composer repositories with package information
Updating dependencies
Lock file operations: 14 installs, 0 updates, 0 removals
  - Locking ezyang/htmlpurifier (v4.16.0)
  - Locking maennchen/zipstream-php (2.1.0)
  - Locking markbaker/complex (3.0.2)
  - Locking markbaker/matrix (3.0.1)
  - Locking michelf/php-markdown (1.9.1)
  - Locking myclabs/php-enum (1.8.4)
  - Locking phpoffice/phpspreadsheet (1.25.2)
  - Locking psr/http-client (1.0.2)
  - Locking psr/http-factory (1.0.2)
  - Locking psr/http-message (1.1)
  - Locking psr/simple-cache (1.0.1)
  - Locking symfony/polyfill-mbstring (v1.27.0)
  - Locking tomk79/filesystem (1.2.3)
  - Locking tomk79/php-excel2html (0.1.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 14 installs, 0 updates, 0 removals
  - Installing ezyang/htmlpurifier (v4.16.0): Extracting archive
  - Installing symfony/polyfill-mbstring (v1.27.0): Extracting archive
  - Installing psr/http-message (1.1): Extracting archive
  - Installing myclabs/php-enum (1.8.4): Extracting archive
  - Installing maennchen/zipstream-php (2.1.0): Extracting archive
  - Installing markbaker/complex (3.0.2): Extracting archive
  - Installing markbaker/matrix (3.0.1): Extracting archive
  - Installing psr/http-client (1.0.2): Extracting archive
  - Installing psr/http-factory (1.0.2): Extracting archive
  - Installing psr/simple-cache (1.0.1): Extracting archive
  - Installing tomk79/filesystem (1.2.3): Extracting archive
  - Installing phpoffice/phpspreadsheet (1.25.2): Extracting archive
  - Installing michelf/php-markdown (1.9.1): Extracting archive
  - Installing tomk79/php-excel2html (0.1.2): Extracting archive
5 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
3 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found

< コード例 >

<?php

require_once( '../vendor/autoload.php' );

ini_set("memory_limit", "-1");
ini_set('max_execution_time', 180);

// == リクエストパラメータ == //
$filename = $_POST["filename"] ? $_POST["filename"] : $_GET["filename"];

if (!$filename) {
  $filename = "/path/filename.xlsx";
}

$src = (new \tomk79\excel2html\main($filename))->get_html(
        array(
            'renderer' => 'strict',
            'cell_renderer' => 'html',
            'render_cell_width' => true,
            'render_cell_background' => true,
            'render_cell_borders' => true,
            'render_cell_align' => true,
            'render_cell_vertical_align' => true,
        ));

print $src;

< 画面例 >