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

**URL:** <https://community.cybozu.dev/t/topic/4966>\
**Category:** kintone 開発相談\
**Created:** [2020 年 3 月 10 日午前 6:43 UTC](https://community.cybozu.dev/t/topic/4966 "2020-03-10T06:43:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Legacy\_Account1740](https://avatars.discourse-cdn.com/v4/letter/l/ed8c4c/32.png) [@Legacy\_Account1740](https://community.cybozu.dev/u/Legacy_Account1740)\
**Post date:** [2020 年 3 月 10 日午前 6:43 UTC](https://community.cybozu.dev/t/topic/4966/1 "2020-03-10T06:43:50Z")

</div>

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

## サンプル

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

### フォーム設定

### コード

[PDF.js](https://mozilla.github.io/pdf.js/)および[swiper](https://swiperjs.com/)を利用しています。 下記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 コード修正いたしました．

---

<div class="post-metadata">

**Author:** ![Legacy\_Account297](https://avatars.discourse-cdn.com/v4/letter/l/47e85d/32.png) [@Legacy\_Account297](https://community.cybozu.dev/u/Legacy_Account297)\
**Post date:** [2020 年 7 月 7 日午前 8:49 UTC](https://community.cybozu.dev/t/topic/4966/2 "2020-07-07T08:49:38Z")

</div>

江田様

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

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

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

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

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

&nbsp;

エラー内容

Uncaught TypeError: Cannot read property ‘fileKey’ of undefined

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1740](https://avatars.discourse-cdn.com/v4/letter/l/ed8c4c/32.png) [@Legacy\_Account1740](https://community.cybozu.dev/u/Legacy_Account1740)\
**Post date:** [2020 年 8 月 12 日午前 9:01 UTC](https://community.cybozu.dev/t/topic/4966/3 "2020-08-12T09:01:24Z")

</div>

青山昌司様

お世話なっております．

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

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

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

```

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

---

<div class="post-metadata">

**Author:** ![Legacy\_Account297](https://avatars.discourse-cdn.com/v4/letter/l/47e85d/32.png) [@Legacy\_Account297](https://community.cybozu.dev/u/Legacy_Account297)\
**Post date:** [2020 年 8 月 12 日午後 12:13 UTC](https://community.cybozu.dev/t/topic/4966/4 "2020-08-12T12:13:36Z")

</div>

江田様

&nbsp;

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

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

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

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

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1409](https://avatars.discourse-cdn.com/v4/letter/l/df788c/32.png) [@Legacy\_Account1409](https://community.cybozu.dev/u/Legacy_Account1409)\
**Post date:** [2020 年 9 月 26 日午前 12:51 UTC](https://community.cybozu.dev/t/topic/4966/5 "2020-09-26T00:51:24Z")

</div>

江田様

&nbsp;

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

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

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

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

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

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1740](https://avatars.discourse-cdn.com/v4/letter/l/ed8c4c/32.png) [@Legacy\_Account1740](https://community.cybozu.dev/u/Legacy_Account1740)\
**Post date:** [2020 年 9 月 29 日午前 7:08 UTC](https://community.cybozu.dev/t/topic/4966/6 "2020-09-29T07:08:10Z")

</div>

gsc-hnd-dad様

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

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

下記リンクから「kintone-ui-component.min.js」と「kintone-ui-component.min.css」をダウンロードして，アプリに追加してください．  
[https://github.com/kintone/kintone-ui-component/tree/master/dist](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);
    });

  });
})();

```

---

<div class="post-metadata">

**Author:** ![Legacy\_Account2338](https://avatars.discourse-cdn.com/v4/letter/l/45deac/32.png) [@Legacy\_Account2338](https://community.cybozu.dev/u/Legacy_Account2338)\
**Post date:** [2020 年 10 月 21 日午前 9:24 UTC](https://community.cybozu.dev/t/topic/4966/7 "2020-10-21T09:24:21Z")

</div>

江田様

江田様のPDFファイルをレコード詳細画面に直接表示する実装方法はとても参考になり、  
かつ、大変勉強させていただきました。  
お手数をおかけしてしまい恐縮なのですが、追加でご質問させていただくことは可能でしょうか。

上記の実装を行なった状態で複数ページのPDFファイルを添付して表示させ、  
レコードを印刷すると表示しているPDFの1ページ分しか印刷することができませんでした。  
レコードの印刷時に「添付された複数ページのPDFファイルの全ページを印刷」するような実装はできるのでしょうか。  
こちら試行錯誤を重ねていたのですが私の方では煮詰まってしまい。。。

お忙しいところ大変恐縮なのですが、ご確認いただきますと幸いです。

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1561](https://avatars.discourse-cdn.com/v4/letter/l/a87d85/32.png) [@Legacy\_Account1561](https://community.cybozu.dev/u/Legacy_Account1561)\
**Post date:** [2021 年 12 月 8 日午前 7:19 UTC](https://community.cybozu.dev/t/topic/4966/8 "2021-12-08T07:19:55Z")

</div>

kintoneにいい感じにPDFが表示できてとても満足です。  
1点、デベロッパーコンソールで「Deprecated API usage: No “GlobalWorkerOptions.workerSrc” specified.」が

js

```
https://cdn.jsdelivr.net/npm/pdfjs-dist@2.10.377/build/pdf.min.js
https://unpkg.com/swiper@7/swiper-bundle.min.js

```

css

```
https://unpkg.com/swiper@7/swiper-bundle.min.css

```

の組み合わせの際に出てしまいました。

```
kintone.events.on(['app.record.detail.show'],function(event){
pdfjsLib.GlobalWorkerOptions.workerSrc = '//cdn.jsdelivr.net/npm/pdfjs-dist@2.10.377/build/pdf.worker.js';
〜〜〜〜〜
}

```

こちらを、入れることで警告が出なくなることがわかりました。

&nbsp;

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex015/uploads/cybozu/original/1X/d5c841c3c5a6cb66eed514001c1b45147c9e1f4f.png) [@system](https://community.cybozu.dev/u/system)\
**Post date:** [2024 年 9 月 6 日午前 4:13 UTC](https://community.cybozu.dev/t/topic/4966/9 "2024-09-06T04:13:28Z")

</div>

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。
