新規投稿
フォローする

添付したPDFをスライド風表示

添付したPowerPointをkintoneで表示出来たらいいなと感じている人は多いかと思います。 PowerPointは困難だったので、今回はPDFをスライド風に表示するサンプルを紹介します。

サンプル

添付したPDFをスライド風に表示します。

フォーム設定

コード

PDF.jsおよびswiperを利用しています。 下記JavaScriptとCSSを読み込んでください。

〇JavaScript

https://cdn.jsdelivr.net/npm/pdfjs-dist@2.2.228/build/pdf.min.js
https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/js/swiper.min.js

〇CSS

https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/css/swiper.min.css

また、JavaScriptについては下記「sample.js」を追加で読み込んでください。
※スライドの表示サイズは、「swiperContainer.style.width」の値で調整してください。

・sample.js

(function() {
  "use strict";
  kintone.events.on([
    'app.record.detail.show'
  ], function(event){
    if(!event.record.添付ファイル.value[0]) return;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', kintone.api.urlForGet('/k/v1/file', {
      fileKey: event.record.添付ファイル.value[0].fileKey
    }, true));
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xhr.responseType = 'blob';
    xhr.addEventListener('load', function(){
      pdfjsLib.getDocument(URL.createObjectURL(xhr.response)).promise.then(function(pdf){
        Promise.all(Array.apply(null, {length: pdf.numPages}).map(function(value, index){
          return pdf.getPage(index+1);
        })).then(function(pages){
          var swiperContainer = document.createElement('div');
          var swiperWrapper = document.createElement('div');
          var swiperButtonPrev = document.createElement('div');
          var swiperButtonNext = document.createElement('div');
          swiperContainer.classList.add('swiper-container');
          swiperWrapper.classList.add('swiper-wrapper');
          swiperButtonPrev.classList.add('swiper-button-prev');
          swiperButtonNext.classList.add('swiper-button-next');
          swiperContainer.style.width = '500px'; //スライドの表示サイズ
          pages.forEach(function(page){
            var swiperSlide = document.createElement('div');
            swiperSlide.classList.add('swiper-slide');
            var canvas = document.createElement('canvas');
            var viewport = page.getViewport({scale: 1});
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            canvas.style.width = '100%';
            canvas.style.height = '100%';
            page.render({
              canvasContext: canvas.getContext('2d'),
              viewport: viewport
            });
            swiperSlide.appendChild(canvas);
            swiperWrapper.appendChild(swiperSlide);
          });
          swiperContainer.appendChild(swiperWrapper);
          swiperContainer.appendChild(swiperButtonPrev);
          swiperContainer.appendChild(swiperButtonNext);
          kintone.app.record.getSpaceElement('space').appendChild(swiperContainer);
          new Swiper('.swiper-container', {
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            }
          });
        });
      });
    });
    xhr.send();
  });
})();

※2020/08/12 コード修正いたしました.

1

5件のコメント

Avatar
青山昌司

江田様

いつもお世話になります。

表示はできるのですが、添付がない場合にエラーが発生してしまいます。

添付がない場合はエラーになりますでしょうか。

また回避する方法はございますでしょうか。

お手すきな際にご確認の程よろしくお願いいたします。

 

エラー内容

Uncaught TypeError: Cannot read property 'fileKey' of undefined

0
Avatar
江田篤史

青山昌司様

お世話なっております.

返信が遅くなり申し訳ございません.
ご指摘ありがとうございます.

元コードの6行目の前あたりに下記を追加してください.

if(!event.record.添付ファイル.value[0]) return;

記事の方も修正いたします.

0
Avatar
青山昌司

江田様

 

お世話になっております。

ご返信ありがとうございます。

コード追加で無事動作確認できました。

今後ともよろしくお願いいたします。

 

1
Avatar
gsc-hnd-dad

江田様

 

お世話になっております。

上記スライド表示のコードうまく作動しまして活用させて頂きたいと思います。大変すばらしいです。

しかしながら一つ課題がでました。

試験的に、添付フィールドに複数のファイルをアップしたところ、最上部にあるファイルのみがプレビュー表示され、その他はダウンロードしか出来ないという事がわかりました。

もし可能なのであればプレビューするファイルの切り替えが出来れば尚助かります。

0
Avatar
江田篤史

gsc-hnd-dad様

お世話になっております.

コメントありがとうございます.
確かに,複数ファイルに対応した方が良さそうですね.

下記リンクから「kintone-ui-component.min.js」と「kintone-ui-component.min.css」をダウンロードして,アプリに追加してください.
https://github.com/kintone/kintone-ui-component/tree/master/dist
「kintone-ui-component.min.js」については,下記の修正版「sample.js」の前に読み込んでください.

・sample.js

(function() {
  "use strict";
  kintone.events.on([
    'app.record.detail.show'
  ], function(event){
    var fieldCode = '添付ファイル';
    var spaceId = 'space';
    if(!event.record[fieldCode].value.length) return;

    var dropdown = new kintoneUIComponent.Dropdown({
      items: event.record[fieldCode].value.map(function(file, index) {
        return {
          label: file.name,
          value: index
        }
      }),
      value: 0
    });
    var containerChunk = document.createElement('div');
    kintone.app.record.getSpaceElement(spaceId).appendChild(dropdown.render());
    kintone.app.record.getSpaceElement(spaceId).appendChild(containerChunk);
    var switchFile = function(index) {
      var containers = containerChunk.childNodes;
      [].forEach.call(containers, function(container){
        container.style.display = 'none';
      });
      containers[index].style.display = 'block';
    }
    dropdown.on('change', switchFile);

    kintone.Promise.all(
      event.record[fieldCode].value.map(function(file){
        var swiperContainer = document.createElement('div');
        swiperContainer.classList.add('swiper-container');
        containerChunk.appendChild(swiperContainer);
        var xhr = new XMLHttpRequest();
        xhr.open('GET', kintone.api.urlForGet('/k/v1/file', {
          fileKey: file.fileKey
        }, true));
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.responseType = 'blob';
        xhr.send();
        return new kintone.Promise(function(resolve){
          xhr.addEventListener('load', resolve);
        }).then(function(){
          return pdfjsLib.getDocument(URL.createObjectURL(xhr.response)).promise;
        }).then(function(pdf){
          return Promise.all(Array.apply(null, {length: pdf.numPages}).map(function(value, index){
            return pdf.getPage(index+1);
          }));
        }).then(function(pages){
          var swiperWrapper = document.createElement('div');
          var swiperButtonPrev = document.createElement('div');
          var swiperButtonNext = document.createElement('div');
          swiperWrapper.classList.add('swiper-wrapper');
          swiperButtonPrev.classList.add('swiper-button-prev');
          swiperButtonNext.classList.add('swiper-button-next');
          swiperContainer.style.width = '500px'; //スライドの表示サイズ
          pages.forEach(function(page){
            var swiperSlide = document.createElement('div');
            swiperSlide.classList.add('swiper-slide');
            var canvas = document.createElement('canvas');
            var viewport = page.getViewport({scale: 1});
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            canvas.style.width = '100%';
            canvas.style.height = '100%';
            page.render({
              canvasContext: canvas.getContext('2d'),
              viewport: viewport
            });
            swiperSlide.appendChild(canvas);
            swiperWrapper.appendChild(swiperSlide);
          });
          swiperContainer.appendChild(swiperWrapper);
          swiperContainer.appendChild(swiperButtonPrev);
          swiperContainer.appendChild(swiperButtonNext);
          new Swiper('.swiper-container', {
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            }
          });
        });
      })
    ).then(function(){
      switchFile(0);
    });

  });
})();
1
サインインしてコメントを残してください。