ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Vue] input으로 받은 이미지 파일로 pdf 미리보기 구현하기
    Vue 2023. 5. 22. 02:12

    프로젝트를 진행하던 중 input을 통해 받은 pdf 혹은 이미지 파일로 pdf 미리보기를 구현해보았다. 단순 pdf 미리보기를 구현하는 정보는 많았으나 유저를 통해 받거나 서버를 통해 받은 파일로 pdf 미리보기를 구현한 경우는 잘 보지 못하여 시도하여 성공한 것을 공유하고자 한다.

    <template>
      <div class="q-gutter-x-md q-mt-md row justify-end">
        <q-btn v-if="status !== 'open'" color="negative" size="17px">데이터 분석</q-btn>
      </div>
    
      <div v-if="status !== 'open'">
        <q-chip color="negative" text-color="white" icon="task_alt" class="text-subtitle1 q-mt-xl" :style="{ height: '40px' }">연구 결과 제출</q-chip>
        <div class="row q-gutter-x-md items-end">
          <q-file v-model="resultFile" label="파일 선택" filled :style="{ width: '400px' }" class="q-mt-md">
            <template v-slot:prepend>
              <q-icon name="attach_file" />
            </template>
          </q-file>
          <q-btn outline color="negative" style="height: 55px" size="16px" @click="reset()">삭제</q-btn>
        </div>
      </div>
    
      <div>
        <q-chip color="negative" text-color="white" icon="task_alt" class="text-subtitle1 q-mt-xl" :style="{ height: '40px' }">연구 결과</q-chip>
        <q-card v-if="!url" class="flex flex-center q-py-lg q-mt-md">
          <div class="row items-center q-pb-md">
            <q-icon name="warning" color="yellow-8" size="25px" class="q-mr-sm"></q-icon>
            <p class="text-h6 q-ma-none">연구 결과 파일을 제출 후 확인하실 수 있습니다.</p>
          </div>
          <p class="q-ma-none">연구 공개 범위를 전체 공개로 선택하시면 '코호트 활용 연구 > 승인 과제 현황' 에서 모든 사용자에게 공개됩니다.</p>
        </q-card>
        <!-- <iframe src="/sample-pdf.pdf#toolbar=0&navpanes=0&scrollbar=0" :style="{ width: '100%', height: '500px' }" class="q-mt-md"></iframe> -->
    
        <iframe v-if="url" :src="url" :style="{ width: '100%', height: '500px' }" class="q-mt-md"></iframe>
      </div>
    </template>
    
    <script>
    import { ref, watch } from 'vue';
    
    export default {
      props: {
        status: String,
      },
      components: {},
    
      setup() {
        let resultFile = ref(null);
        let url = ref(null);
    
        const reset = () => {
          if (resultFile.value) {
            if (window.confirm('제출된 결과파일을 삭제하시겠습니까?')) {
              url.value = null;
              resultFile.value = null;
            }
          }
        };
    
        watch(resultFile, (newFile) => {
          if (newFile) url.value = window.URL.createObjectURL(newFile) + '#toolbar=0&navpanes=0&scrollbar=0';
        });
    
        return {
          resultFile,
          url,
          reset,
        };
      },
    };
    </script>

    핵심을 말하자면, resultFile이라는 변수를 통해 유저를 통해 이미지 파일을 받고 나서 pdf 미리보기에 필요한 iframe 태그에 들어간 url을 만들어준다. url을 만드는 방법은 window.URL.createObjectURL(newFile)와 같이 받은 파일을 그대로 해당 함수에 넣어주면 된다. 또한 resultFile이라는 변수가 유저를 통해 변경되자마자 dom에 반영되어야하므로 url로 바꾸는 과정은 watch를 사용하였다. 그런데 이렇게 url을 만드는 과정에서 나는 pdf 미리보기의 toolbar 기능을 제거하기위해  '#toolbar=0&navpanes=0&scrollbar=0'을 추가하여 구현하였다.

     

    결과는 다음과 같다. 유저가 결과 파일을 제출하기 전에는 제출 후 확인할 수 있다는 문구가 나타난다. 제출 전 후는 url 변수가 null이냐 아니냐에 따라 v-if를 적용한 것으로 위 코드로 확인할 수 있다. url 변수가 초기값 null이라면 제출 전이므로 제출하라는 문구가 나타나고, null이 아닌 값이라면 제출 후이므로 pdf 미리보기가 나타난다.

     

    다음과 같이 제출 후에는 제출 후 확인할 수 있다는 문구 대신 pdf 미리보기가 예쁘게 나타나는 것을 볼 수 있다.

Designed by Tistory.