2017-09-17 3 views
0

나는 아주 간단한 응용 프로그램을 가지고 있습니다. 사용자는 웹 프런트 엔드를 통해 PDF 파일을 Postgres 데이터베이스에 업로드합니다. 그 pdf는 pdfjs를 통해 브라우저에서 렌더링되어야합니다.플라스크/포스트 그레스 - PDF 파일로 PDF보기

내 문제는 인코딩 문제라고 확신하지만이 문제에 대해 독자적으로 대답 할 수있을만큼 인코딩을 잘 이해하지 못합니다.

내 모델 :

class Lesson(Base): 
    __tablename__ = 'lessons' 

    # Name of the lesson 
    lesson_order = db.Column(db.Enum(LessonIndexes), nullable=False) 
    name = db.Column(db.String(128), nullable=False) 
    summary = db.Column(db.String(500)) 
    lesson_plan_id = db.Column(db.Integer(), ForeignKey('lesson_plans.id'), nullable=False) 
    pdf = db.Column(db.LargeBinary()) 

내 컨트롤러 :

@mod_lp.route('/<lesson_plan_id>/create_lesson', methods=["POST"]) 
def create_lesson(lesson_plan_id): 
    form = LessonForm() 
    file = request.files['pdf'] # type: FileStorage 

    if form.validate_on_submit(): 
     file = request.files['pdf'] 
     lesson = Lesson(form.lesson_order.data, form.name.data, form.summary.data, lesson_plan_id, 
         pdf=file.read() # this line here 
         ) 
     db.session.add(lesson) 
     db.session.commit() 
    return redirect(url_for('lesson_plan.show', lesson_plan_id=lesson_plan_id)) 

이 같은 것을보고 데이터를 저장 :

%PDF-1.4 
%���� 
1 0 obj 
<</Creator (Mozilla/5.0 \(Macintosh; Intel Mac OS X 10_12_6\) AppleWebKit/537.36 \(KHTML, like Gecko\) Chrome/60.0.3112.113 Safari/537.36) 
/Producer (Skia/PDF m60) 
/CreationDate (D:20170916222407+00'00') 
/ModDate (D:20170916222407+00'00')>> 
endobj 
2 0 obj 
<</Filter /FlateDecode 
/Length 1370>> stream 
x���ݎ�4��<������� qq$8�@%`aB�H�_�����T�E���ړ�c'�t�Z��[������}�{�I���@��� 

(etc...) 

내 기능인 자바 스크립트를 (PDFJS에서 촬영을, 안녕하세요 세계) :

var pdfString = "{{ pdf_data}}"; 
var pdfData = atob(pdfString); 
if (pdfData) { 
    var loadingTask = PDFJS.getDocument({data: pdfData}); 
    loadingTask.promise.then(function (pdf) { 
     console.log('PDF loaded'); 

     // Fetch the first page 
     var pageNumber = 1; 
     pdf.getPage(pageNumber).then(function (page) { 
      console.log('Page loaded'); 

      var scale = 1.5; 
      var viewport = page.getViewport(scale); 

      // Prepare canvas using PDF page dimensions 
      var canvas = document.getElementById('pdf-canvas'); 
      var context = canvas.getContext('2d'); 
      canvas.height = viewport.height; 
      canvas.width = viewport.width; 

      // Render PDF page into canvas context 
      var renderContext = { 
       canvasContext: context, 
       viewport: viewport 
      }; 
      var renderTask = page.render(renderContext); 
      renderTask.then(function() { 
       console.log('Page rendered'); 
      }); 
     }); 
    }, function (reason) { 
     // PDF loading error 
     console.error(reason); 
    }); 

내가 가진 현재의 에러입니다 : 내가 해봤

6:108 Uncaught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded. 

일 :

file.stream.getvalue() 

file.stream.getvalue().decode("latin-1") # for whatever reason, this was the only 'decode' that didn't throw an error 

file.stream.getvalue().decode("latin-1").encode() 

base64.b64encode(file.stream.getvalue().decode("latin-1").encode()) 

그러나이 모든 다양한 방법으로 실패했습니다. UPDATE :

내 템플릿에 데이터베이스에 바이너리 데이터를 전송하는 경우 :

pdf_data = lesson.pdf 

과에 atob를 호출 잊어 :

:

var pdfData = pdfString; 
     if (pdfData) { 
... 

나는이 오류

Error: Invalid XRef stream header 
pdf.worker.js:340  at error (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:340:17) 
    at XRef_readXRef [as readXRef] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:20943:13) 
    at XRef_parse [as parse] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:20613:28) 
    at PDFDocument_setup [as setup] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:26445:17) 
    at PDFDocument_parse [as parse] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:26336:12) 
    at http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:36120:28 
    at Promise (<anonymous>) 
    at LocalPdfManager_ensure [as ensure] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:36115:14) 
    at LocalPdfManager.BasePdfManager_ensureDoc [as ensureDoc] (http://0.0.0.0:8080/static/js/pdfjs/build/pdf.worker.js:36067:19) 

답변

1

atob은 base64 인코딩 된 문자열을 예상합니다. 적어도 atob에 대한 성공적인 호출을 얻으려면 기본적인 예제가 있습니다. 확실히 이것은 당신이보고있는 문제입니다. 아마도 base64로 인코딩 된 내용을 그 postgres 테이블에 저장할 수 있기 때문에 항상 디코드 할 필요가 없습니다. 'source.pdf'는 디스크에있는 샘플 PDF입니다. 그러나 이것을 postgres 테이블의 데이터로 바꿀 수 있습니다.

from flask import Flask, request, render_template 
import base64 

app = Flask(__name__) 


@app.route("/testing", methods=["GET"]) 
def get_test_file(): 
    with open("source.pdf", "rb") as data_file: 
     data = data_file.read() 
    encoded_data = base64.b64encode(data).decode('utf-8') 
    return render_template("test.html", encoded_data=encoded_data) 

test.html를

<html> 
<head> 
</head> 
<body> 
    <script> 
    var encoded_data = '{{ encoded_data }}'; 
    var pdf_data = atob(encoded_data); 
    </script> 
</body> 
</html> 
+0

와우를 flask_app.py! 간단하지만, 나는 완전히 그것을 놓쳤다. 감사! DB 또는 b64로 인코딩 된 문자열에 이진 데이터를 기록해야합니까? – Jeff

+0

전혀 문제 없습니다. 제프. 솔직히, 당신은 어느 쪽이든 데이터베이스에 저장할 수 있습니다 종류는 개인적인 취향에 달려 있습니다. – Kyle