2012-10-13 19 views
37

का उपयोग कर वेब-सेवा से लौटाई गई बाइनरी स्ट्रिंग से पीडीएफ फ़ाइल कैसे बनाएं I AJAX अनुरोध से प्रतिक्रिया के रूप में मुझे प्राप्त होने वाली बाइनरी स्ट्रीम से पीडीएफ फाइल बनाने की कोशिश कर रहा हूं।जावास्क्रिप्ट

वाया XmlHttpRequest मैं डेटा निम्नलिखित प्राप्त करते हैं: uri:

%PDF-1.4.... 
..... 
....hole data representing the file 
.... 
%% EOF 

क्या मैं अब तक की कोशिश की, डेटा के माध्यम से अपने डेटा एम्बेड करने के लिए किया गया था।

अब, इसमें कुछ भी गलत नहीं है। यह ठीक काम करता है। दुर्भाग्यवश यह आईई 9, और एफएफ में काम नहीं करता है।

संभावित कारण यह हो सकता है कि एफएफ और आईई 9 में डेटा-यूरी के उपयोग के साथ समस्याएं हैं।

अब, मैं किसी भी समाधान की तलाश कर रहा हूं जो सभी ब्राउज़रों के लिए काम करता है।

// responseText encoding 
pdfText=$.base64.decode($.trim(pdfText)); 

// Now pdfText contains %PDF-1.4 ...... data...... %%EOF 

var winlogicalname = "detailPDF"; 
var winparams = 'dependent=yes,locationbar=no,scrollbars=yes,menubar=yes,'+ 
      'resizable,screenX=50,screenY=50,width=850,height=1050'; 

var htmlText = '<embed width=100% height=100%' 
        + ' type="application/pdf"' 
        + ' src="data:application/pdf,' 
        + escape(pdfText) 
        + '"></embed>'; 

       // Open PDF in new browser window 
       var detailWindow = window.open ("", winlogicalname, winparams); 
       detailWindow.document.write (htmlText); 
       detailWindow.document.close(); 

जैसा कि मैंने कहा .... यह ओपेरा और क्रोम (सफारी परीक्षण नहीं) के लिए ठीक काम करता है:

यहाँ मेरी कोड है। आईई या एफएफ का उपयोग करके एक खाली नई विंडो लाएगी।

क्या उपयोगकर्ता को इसे डाउनलोड करने के लिए फ़ाइल सिस्टम पर पीडीएफ फ़ाइल बनाने जैसे कोई समाधान है?

मुझे एक ऐसे समाधान की आवश्यकता है जो कम से कम आईई, एफएफ, ओपेरा, क्रोम और सफारी में सभी ब्राउज़रों में काम करे।

मुझे वेब-सेवा कार्यान्वयन को संपादित करने की कोई अनुमति नहीं है। इसलिए इसे क्लाइंट-साइड पर समाधान होना था।

कोई विचार ???

+1

मुझे लगता है कि यह बेहतर हो हर कोई एक सेवा है जो करने के लिए पीडीएफ फाइलों को डाउनलोड करता है लिखने के लिए होगा एक फ़ोल्डर, वेबसर्वर स्थिर फाइलों को सेवा दें। पथ पर आधारित, फ़ाइल के लिए अपना यूआरएल बनाएं। –

+0

@RrinivasReddyThatiparthy से सहमत। एक अस्थायी फ़ाइल में डाउनलोड करें और उपयोगकर्ता को फ़ाइल की सेवा करें। ऑब्जेक्ट और एम्बेड टैग के संयोजन का उपयोग करके निश्चित रूप से आवश्यक होने पर आप इनलाइन को प्रदर्शित कर सकते हैं - यह प्रश्न देखें: http://stackoverflow.com/questions/1244788/embed-vs-object/1244871#1244871 – mccannf

+0

आपको इसकी आवश्यकता क्यों है जेएस के साथ डेटा पकड़ो? क्या आप स्थान = के साथ बस नई विंडो नहीं खोल सकते हैं? – sander

उत्तर

2

मैंने हाल ही में इस विषय पर एक और सवाल देखा (streaming pdf into iframe using dataurl only works in chrome)।

मैंने Ast में pdfs का निर्माण किया है और उन्हें ब्राउज़र पर स्ट्रीम किया है। मैं उन्हें पहले एफडीएफ के साथ बना रहा था, फिर एक पीडीएफ कक्षा के साथ मैंने खुद लिखा - प्रत्येक मामले में पीडीएफ को यूआरएल के माध्यम से पारित कुछ जीईटी पैरा के आधार पर एक COM ऑब्जेक्ट से पुनर्प्राप्त डेटा से बनाया गया था।

AJAX कॉल में प्राप्त आपके डेटा को देखने से, ऐसा लगता है कि आप लगभग वहां हैं। मैंने अब कुछ वर्षों से कोड के साथ नहीं खेला है और मैंने इसे दस्तावेज भी नहीं किया है, लेकिन मुझे लगता है कि आपको बस इतना करना है कि यूआरएल होने का लक्ष्य यूआरएल हो आप से पीडीएफ मिलता है। हालांकि यह काम नहीं कर सकता है - पीडीएफ को आउटपुट करने वाली फ़ाइल को पहले एचटीएमएल प्रतिक्रिया शीर्षलेख को आउट करना पड़ सकता है। ,

//We send to a browser 
header('Content-Type: application/pdf'); 
if(headers_sent()) 
    $this->Error('Some data has already been output, can\'t send PDF file'); 
header('Content-Length: '.strlen($this->buffer)); 
header('Content-Disposition: inline; filename="'.$name.'"'); 
header('Cache-Control: private, max-age=0, must-revalidate'); 
header('Pragma: public'); 
ini_set('zlib.output_compression','0'); 
echo $this->buffer; 

तो, इधर-उधर ajax कॉल पूर्ण प्रतिक्रिया पाठ मैं वास्तव में कुछ यह क्या है नहीं किया जा सकता देखे बिना हालांकि मैं कर रहा हूँ:

संक्षेप में, यह उत्पादन कोड मैं प्रयोग किया जाता है यह सोचने के इच्छुक है कि जिस पीडीएफ को आप अनुरोध कर रहे हैं उसे आउटपुट करने वाले कोड केवल उपरोक्त कोड में अंतिम पंक्ति के समतुल्य हो सकते हैं। यदि यह कोड आपके ऊपर नियंत्रण रखता है, तो मैं हेडर सेट करने का प्रयास करता हूं - इस प्रकार ब्राउज़र केवल प्रतिक्रिया टेक्स्ट से निपट सकता है - आपको इससे कोई काम करने की परेशानी नहीं है।

मैंने बस पीडीएफ के लिए एक यूआरएल बनाया जो मैं चाहता था (एक समय सारिणी) फिर एक स्ट्रिंग बनाई जिसने वांछित एसई, आईडी इत्यादि के आईफ़्रेम के लिए एचटीएमएल का प्रतिनिधित्व किया जो यूआरएल के रूप में निर्मित यूआरएल का इस्तेमाल करता था। जैसे ही मैंने एक div के आंतरिक HTML को निर्मित HTML स्ट्रिंग पर सेट किया, ब्राउज़र ने पीडीएफ के लिए पूछा और फिर इसे प्राप्त होने पर प्रदर्शित किया।

function showPdfTt(studentId) 
{ 
    var url, tgt; 
    title = byId("popupTitle"); 
    title.innerHTML = "Timetable for " + studentId; 
    tgt = byId("popupContent"); 
    url = "pdftimetable.php?"; 
    url += "id="+studentId; 
    url += "&type=Student"; 
    tgt.innerHTML = "<iframe onload=\"centerElem(byId('box'))\" src='"+url+"' width=\"700px\" height=\"500px\"></iframe>"; 
} 

संपादित करें: उल्लेख करना भूल गया - आप इस तरीके से बाइनरी पीडीएफ भेज सकते हैं। जिन धाराओं में वे शामिल हैं उन्हें एसीआई 85 या हेक्स एन्कोडेड होने की आवश्यकता नहीं है। मैंने पीडीएफ में सभी धाराओं पर झुकाव का इस्तेमाल किया और यह ठीक काम किया।

4

मैं इस बदल दिया है:

var htmlText = '<embed width=100% height=100%' 
       + ' type="application/pdf"' 
       + ' src="data:application/pdf,' 
       + escape(pdfText) 
       + '"></embed>'; 

var htmlText = '<embed width=100% height=100%' 
       + ' type="application/pdf"' 
       + ' src="data:application/pdf;base64,' 
       + escape(pdfText) 
       + '"></embed>'; 

लिए और यह मेरे लिए काम किया।

+0

एंड्रॉइड ब्राउज़र में काम किया? – isobretatel

+1

यह काम नहीं करता है। – Juanjo

+0

@Alexandre, यह समाधान स्केल नहीं करता है। – Pacerier

3

मैं PHP में काम करता हूं और सर्वर से वापस भेजे गए बाइनरी डेटा को डीकोड करने के लिए फ़ंक्शन का उपयोग करता हूं। मैं जानकारी को एक साधारण file.php में इनपुट निकालता हूं और फ़ाइल को अपने सर्वर के माध्यम से देखता हूं और सभी ब्राउज़र पीडीएफ आर्टेफैक्ट प्रदर्शित करते हैं।

<?php 
    $data = 'dfjhdfjhdfjhdfjhjhdfjhdfjhdfjhdfdfjhdf==blah...blah...blah..' 

    $data = base64_decode($data); 
    header("Content-type: application/pdf"); 
    header("Content-Length:" . strlen($data)); 
    header("Content-Disposition: inline; filename=label.pdf"); 
    print $data; 
    exit(1); 

?> 
+4

-1। दिलचस्प है लेकिन उपयोगकर्ता ने पूछा नहीं है। उन्होंने क्लाइंट साइड में ऐसा करने के लिए विशेष रूप से वेब सेवा से जावास्क्रिप्ट से पूछा, मान लीजिए कि उपयोगकर्ता वेब सेवा को भी नियंत्रित नहीं करता है या वह सर्वर साइड भाषा का उपयोग कर रहा है। – Juanjo

2

बेस 64 के साथ @alexandre का उत्तर चाल है।

स्पष्टीकरण क्यों कि IE के लिए काम करता है यहाँ

https://en.m.wikipedia.org/wiki/Data_URI_scheme

है हैडर 'प्रारूप' जहां लिखा है

कुछ ब्राउज़र (क्रोम, ओपेरा, सफारी, फ़ायरफ़ॉक्स) एक गैर स्वीकार तहत मानक दोनों को ऑर्डर करना; बेस 64 और; कर्सेट की आपूर्ति की जाती है, जबकि इंटरनेट एक्सप्लोरर की आवश्यकता है कि वर्णसेट का विनिर्देश बेस 64 टोकन से पहले होना चाहिए।

2

आप PDF.js का उपयोग जावास्क्रिप्ट से पीडीएफ फाइलों को बनाने के लिए ... यह कोड आसान है सकते हैं ... यह अपने संदेह का समाधान उम्मीद !!!

सम्मान!

18

क्या उपयोगकर्ता को इसे डाउनलोड करने के लिए क्रम में फ़ाइल सिस्टम पर पीडीएफ फ़ाइल बनाने जैसे कोई समाधान है?

कोशिश blob को XMLHttpRequest की responseType की स्थापना, window.open के लिए a तत्व पर download विशेषता प्रतिस्थापन

var request = new XMLHttpRequest(); 
request.open("GET", "/path/to/pdf", true); 
request.responseType = "blob"; 
request.onload = function (e) { 
    if (this.status === 200) { 
     // `blob` response 
     console.log(this.response); 
     // create `objectURL` of `this.response` : `.pdf` as `Blob` 
     var file = window.URL.createObjectURL(this.response); 
     var a = document.createElement("a"); 
     a.href = file; 
     a.download = this.response.name || "detailPDF"; 
     document.body.appendChild(a); 
     a.click(); 
     // remove `a` following `Save As` dialog, 
     // `window` regains `focus` 
     window.onfocus = function() {      
      document.body.removeChild(a) 
     } 
    }; 
}; 
request.send(); 
+0

यह मेरे लिए पूरी तरह से काम करता है। धन्यवाद – Juanjo

+2

अंतिम 'removeChild (ए)' को छोड़कर, मेरे लिए भी ठीक काम करता है, जो एक त्रुटि लौटाता है (कुछ "नोड नहीं मिला")। तो मैंने अभी 'window.onfocus' पर इस निष्कासन को ट्रिगर नहीं किया है और इसके बजाय' a.click() 'के ठीक बाद' document.body.removeChild (ए) 'को सीधे डाला है। – zezollo

+0

@zezollo 'विंडो' 'क्लिक' ईवेंट से पहले फोकस प्राप्त कर रहा है? शायद 'document.body.appendChild (ए); a.onclick = function() { window.onfocus = function() { document.body.removeChild (ए) के साथ प्रतिस्थापित किया जा सकता है; window.onfocus = null; } } a.click() ' – guest271314

2

ब्राउज़र का पता लगाने और क्रोम के लिए डेटा-URI का उपयोग .pdf फ़ाइल के रूप में XMLHttpRequest से प्रतिक्रिया की डाउनलोड अनुमति देने के लिए और अन्य ब्राउज़रों के लिए नीचे PDF.js का उपयोग करें।

PDFJS.getDocument(url_of_pdf) 
.then(function(pdf) { 
    return pdf.getPage(1); 
}) 
.then(function(page) { 
    // get a viewport 
    var scale = 1.5; 
    var viewport = page.getViewport(scale); 
    // get or create a canvas 
    var canvas = ...; 
    canvas.width = viewport.width; 
    canvas.height = viewport.height; 

    // render a page 
    page.render({ 
     canvasContext: canvas.getContext('2d'), 
     viewport: viewport 
    }); 
}) 
.catch(function(err) { 
    // deal with errors here! 
}); 
8

मुझे पता है यह एक नहीं बल्कि पुराने सवाल है, लेकिन यहाँ समाधान मैं आज के साथ आया है:

doSomethingToRequestData().then(function(downloadedFile) { 
    // create a download anchor tag 
    var downloadLink  = document.createElement('a'); 
    downloadLink.target = '_blank'; 
    downloadLink.download = 'name_to_give_saved_file.pdf'; 

    // convert downloaded data to a Blob 
    var blob = new Blob([downloadedFile.data], { type: 'application/pdf' }); 

    // create an object URL from the Blob 
    var URL = window.URL || window.webkitURL; 
    var downloadUrl = URL.createObjectURL(blob); 

    // set object URL as the anchor's href 
    downloadLink.href = downloadUrl; 

    // append the anchor to document body 
    document.body.append(downloadLink); 

    // fire a click event on the anchor 
    downloadLink.click(); 

    // cleanup: remove element and revoke object URL 
    document.body.removeChild(downloadLink); 
    URL.revokeObjectURL(downloadUrl); 
} 
+1

क्या आपको AJAX के साथ ऐसा करने की ज़रूरत है? आप आसानी से यूआरएल को href के रूप में डाल सकते हैं और इसे सीधे डाउनलोड कर सकते हैं (लेकिन केवल अगर यह एक आसान अनुरोध है) – Endless

+0

एक साधारण एंकर का उपयोग करना हमारे मामले में एक विकल्प नहीं है, AJAX आवश्यक था। –