PDF Blob - 팝업창에 콘텐츠가 표시되지 않음
저는 지난 며칠 동안 이 문제에 대해 연구하고 있습니다.스트림을 표시하려고 시도하지 않고<embed src>
태그를 새 창에 표시하려고 했습니다.
새 창에는 PDF 컨트롤만 표시됩니다. )
pdf의 내용이 왜 표시되지 않는지 아십니까?
코드:
$http.post('/fetchBlobURL',{myParams}).success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
를 설정할 필요가 있습니다.responseType
로.arraybuffer
를 작성하려면blob
응답 데이터:
$http.post('/fetchBlobURL',{myParams}, {responseType: 'arraybuffer'})
.success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
상세 정보:데이터 전송 중_및 수신 중_이진수_데이터
설정했을 경우{ responseType: 'blob' }
, 작성할 필요가 없습니다.Blob
혼자 힘으로.응답 내용을 기반으로 URL을 작성할 수 있습니다.
$http({
url: "...",
method: "POST",
responseType: "blob"
}).then(function(response) {
var fileURL = URL.createObjectURL(response.data);
window.open(fileURL);
});
나는 Angular를 사용한다.JS v1.3.4
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
JS 컨트롤러:
'use strict';
angular.module('xxxxxxxxApp')
.controller('MathController', function ($scope, MathServicePDF) {
$scope.downloadPdf = function () {
var fileName = "test.pdf";
var a = document.createElement("a");
document.body.appendChild(a);
MathServicePDF.downloadPdf().then(function (result) {
var file = new Blob([result.data], {type: 'application/pdf'});
var fileURL = window.URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
});
JS 서비스:
angular.module('xxxxxxxxApp')
.factory('MathServicePDF', function ($http) {
return {
downloadPdf: function () {
return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java REST 웹 서비스 - 봄 MVC:
@RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity<byte[]> getPDF() {
FileInputStream fileStream;
try {
fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf"));
byte[] contents = IOUtils.toByteArray(fileStream);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String filename = "test.pdf";
headers.setContentDispositionFormData(filename, filename);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
return response;
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
// I used this code with the fpdf library.
// Este código lo usé con la libreria fpdf.
var datas = json1;
var xhr = new XMLHttpRequest();
xhr.open("POST", "carpeta/archivo.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status === 200) {
var blob = new Blob([xhr.response], {type: 'application/pdf'});
const url = window.URL.createObjectURL(blob);
window.open(url,"_blank");
setTimeout(function () {
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(datas)
, 100
})
}
};
xhr.send("men="+datas);
데이터가 바이트 배열인 경우 응답 유형을 설정할 필요가 없습니다. 데이터를 BLOB로 전달하기 전에 Uint8Array로 변환해야 합니다.
예:
let byteArray = new Uint8Array(data)
let file = new Blob(
[byteArray],
{type: 'application/pdf'}
)
저는 좋아요.
데이터가 byteArray가 아닌 경우 반드시 byteArray로 변환하고 위의 단계를 따라 작동하십시오.
//For example if your data is base-64 encoded string.
let byteChars = atob(data); //To decrypt data
let dataArray = = new Array(byteChars.length);
for(let i=0; i< byteChars.length; i++){
dataArray[i] = byteChars.charCodeAt(i);
}
let byteArray = new Uint8Array(dataArray)
let file = new Blob(
[byteArray],
{type: 'application/pdf'}
)
오래된 일이라는 건 알지만, 이 일이 저를 올바른 방향으로 인도해줬기 때문에, 만약 다른 사람이 이곳에 도착한다면 제가 하고 있는 일을 공유해야겠다고 생각했습니다.나는 Angular btw를 사용하지 않는다.
사용자는 파일을 보거나 다운로드할 수 있습니다.2개의 버튼 또는 2개의 링크를 선택할 수 있습니다.
<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="Download File" data-formid="{{ @your-id }}" data-forcedownload="1">
<i class="fas fa-file-download"></i>
</button>
<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="View File" data-formid="{{ @your-id }}" data-forcedownload="0">
<i class="fas fa-search"></i>
</button>
xhr2의 네이티브 플러그인으로 jQuery를 사용하고 있습니다.링크/버튼을 처리합니다.
$('.download-form').click(function(event) {
event.preventDefault();
let fid = $(this).data('formid');
let force_download = $(this).data('forcedownload');
$.ajax({
url: '/download',
dataType: 'native',
type: 'POST',
xhrFields: {
responseType: 'blob'
},
data: {
//you can send any parameters via POST here
personID: "{{ @personID }}",
file_record_id: pfid,
file_type: "contract_form",
dept: "your-dept",
file_category: "fcategory",
force_download: force_download
},
success: function(blob, status, xhr){
if (xhr.getResponseHeader('Custom-FileError')>1) {
alertify.error(xhr.getResponseHeader('Custom-ErrorMsg'));
}else{
//I thought this would work when viewing the PDF but it does not.
blob.name = xhr.getResponseHeader('Custom-FileName');
var fileURL = URL.createObjectURL(blob);
if (xhr.getResponseHeader('Custom-ForceDownload')==1) {
window.open(fileURL);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=xhr.getResponseHeader('Custom-FileName');
link.click();
}else{
file_modal(fileURL,'Any Title');
}
}
}
})
});
그럼, 모달의 자바스크립트를 좀 더 주세요.
function file_modal(blob,the_title)
{
let spinner = "<div class='text-center'><i class='fa fa-spinner fa-spin fa-5x fa-fw'></i></div>";
$("#modal_static_label").html('Loading');
$("#modal_static .modal-body").html(spinner);
if (blob.length > 1) {
$("#modal_static").modal("show");
$("#modal_static_label").html(the_title);
$("#modal_static .modal-body").empty().append('<iframe src='+blob+' width="100%" height="500px" style="border:none;"></iframe>');
}else{
$("#modal_static .modal-body").empty().html('File error');
}
$("#modal_static .modal-footer").html('<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>');
}
서버측에서는, 다음과 같은 커스텀 헤더를 송신할 필요가 있습니다.[ PHP ]
header("Content-length: $file_size");
header("Custom-FileError: 0");
header("Custom-FileName: ".$this->params['original_filename']);
header("Custom-ForceDownload: ".$this->params['force_download']);
header('Content-Type: '.$web->mime($this->full_path.$this->new_file_name));
readfile($this->full_path.$this->new_file_name);
사용자가 "view"를 클릭하면 모달에 PDF가 표시되고 "download"를 클릭하면 다운로드 창에 원하는 파일 이름이 표시됩니다.저는 이것을 10MB 미만의 PDF 파일로 테스트했고 예상대로 작동합니다.
누가 이걸 유용하게 봤으면 좋겠어요.
며칠 동안 고군분투하다 마침내 나에게 효과가 있었던 해결책이 아래에 제시되었다.난 그 일을 해야 했다.window.print()
새 창에서 PDF를 사용해야 합니다.
var xhr = new XMLHttpRequest();
xhr.open('GET', pdfUrl, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this['status'] == 200) {
var blob = new Blob([this['response']], {type: 'application/pdf'});
var url = URL.createObjectURL(blob);
var printWindow = window.open(url, '', 'width=800,height=500');
printWindow.print()
}
};
xhr.send();
PDF 로딩 및 새 창 인쇄에 관한 주의사항.
- iframe을 사용하여 pdf를 새 창에 로드하면 작동하지만 url이 외부 URL이면 인쇄가 작동하지 않습니다.
- 브라우저 팝업이 허용되어야만 작동합니다.
- 외부 URL에서 iframe을 로드하여
window.print()
합니다.iframe
다만, 수동으로 인쇄를 기동할 수 있기 때문에, 동작합니다.
문제는 올바른 형식으로 변환되지 않았다는 것입니다.printPreview(binaryPDFDATA) 기능을 사용하여 바이너리 PDF 데이터의 인쇄 미리보기 대화상자를 가져옵니다.인쇄 대화상자를 열지 않으려면 스크립트 부분에 주석을 달 수 있습니다.
printPreview = (data, type = 'application/pdf') => {
let blob = null;
blob = this.b64toBlob(data, type);
const blobURL = URL.createObjectURL(blob);
const theWindow = window.open(blobURL);
const theDoc = theWindow.document;
const theScript = document.createElement('script');
function injectThis() {
window.print();
}
theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
theDoc.body.appendChild(theScript);
};
b64toBlob = (content, contentType) => {
contentType = contentType || '';
const sliceSize = 512;
// method which converts base64 to binary
const byteCharacters = window.atob(content);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
}); // statement which creates the blob
return blob;
};
결국 아래 코드를 사용하여 pdf를 다운로드하게 되었습니다.
function downloadPdfDocument(fileName){
var req = new XMLHttpRequest();
req.open("POST", "/pdf/" + fileName, true);
req.responseType = "blob";
fileName += "_" + new Date() + ".pdf";
req.onload = function (event) {
var blob = req.response;
//for IE
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
}
};
req.send();
}
주의: 이거.file은 base64 파일이어야 합니다.
언급URL : https://stackoverflow.com/questions/21729451/pdf-blob-pop-up-window-not-showing-content
'sourcecode' 카테고리의 다른 글
React Native에서 누를 때 버튼 스타일 변경 (0) | 2023.02.23 |
---|---|
jquery를 사용하여 단추를 동적으로 추가하는 방법 (0) | 2023.02.23 |
Springfox swagger-ui.html이 기본 URL을 추론할 수 없음 - 쿠키 누락으로 인해 발생함 (0) | 2023.02.23 |
AngularJS + 돛.js (0) | 2023.02.23 |
스프링 부트 서버를 시작할 수 없습니다. (0) | 2023.02.23 |