“我想将从基于Spring的静态Web服务发送的.pdf文件下载到我的angular应用程序。如何下载它,我在我的angular应用程序或spring boot上缺少某些代码吗?”
我正在将来自Angular 6应用的HTTP GET请求发送到我的spring-boot服务器,该服务器会生成一个.pdf文件,然后将这个.pdf文件作为blob发送给我, 但是当我尝试在有角度的一侧创建blob并打开pdf时,它显示以下错误:
。错误错误:请求正文不是Blob或数组缓冲区
我在StackOverflow上访问了以下问题,以找到一些解决方案: 1. PDF Blob is not showing content, Angular 2 2. How can I get access to the Angular 2 http response body without converting it to string or json? 3. converting byte stream in HTTPResponse body into a pdf file 4. Send File with SpringBoot to Angular2
在Angular应用中: 组件:
服务:getPDF(){ this.apiService.getPDF(this.invoiceId) .subscribe( (data) => { //data.blob() doesnt work properly var file = new Blob([data.blob()], { type: 'application/pdf' }) var fileURL = URL.createObjectURL(file); window.open(fileURL); // if you want to open it in new tab var a = document.createElement('a'); a.href = fileURL; a.target = '_blank'; a.download = 'bill.pdf'; document.body.appendChild(a); a.click(); }, (error) => { console.log('getPDF error: ',error); } ); }
public class Chat extends AppCompatActivity {
private DatabaseReference Database;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
final UserLocalStore localStore = new UserLocalStore(Chat.this);
Database = FirebaseDatabase.getInstance().getReference("Messages");
final TextView Chat_Window=(TextView)findViewById(R.id.chat_window);
Database.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @androidx.annotation.Nullable String s) {
Log.e("DatasnapShot",dataSnapshot.getKey().toString());
Chat_Window.setText(dataSnapshot.getValue().toString());
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @androidx.annotation.Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @androidx.annotation.Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Button SendMessage = (Button)findViewById(R.id.send);
SendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String messageText = Chat_Window.getText().toString();
Database.push().setValue((localStore.getUserData().get(0).toString()));
Database.push().setValue(ChatType.getText().toString());
Chat_Window.append(ChatType.getText().toString());
ChatType.setText("");
}
});
Button Signout = (Button)findViewById(R.id.signout);
{
Signout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UserLocalStore localStore=new UserLocalStore(Chat.this);
localStore.LogOut();
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(Chat.this,MainActivity.class);
startActivity(intent);
}
});
}
}
}
在春季启动中:
控制器:
getPDF(invoiceId : number) { this.url = this.main_url + '/invoices/generatepdf/'+invoiceId; const headers = new Headers({ 'Content-Type': 'application/json', "Authorization": authorization, responseType : 'blob'}); return this.http.get(this.url, { headers : headers}) .pipe(map( (response) => { return response; }, (error) => { console.log(error.json()); } )); }
ServiceImplementation:
@RestController @RequestMapping("/invoices") public class InvoiceController { @Autowired InvoiceService invoiceService; @GetMapping(path = "/generatepdf/{invoiceId}") public void generateInvoicePdf(@PathVariable Integer invoiceId, HttpServletRequest request,HttpServletResponse response) { invoiceService.generateInvoicePdf(invoiceId, request, response); }
我希望在浏览器中下载一个.pdf文件并打开它并查看其内容,但是却出现了错误:
core.js:15724错误错误:请求正文不是Blob或数组缓冲区 在Response.push ../ node_modules/@angular/http/fesm5/http.js.Body.blob(http.js:782) 在SafeSubscriber._next(invoice-details.component.ts:212) 在SafeSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.SafeSubscriber .__ tryOrUnsub(Subscriber.js:196) 在SafeSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.SafeSubscriber.next(Subscriber.js:134) 在Subscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber._next(Subscriber.js:77) 在Subscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber.next(Subscriber.js:54) 在MapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / operators / map.js.MapSubscriber._next(map.js:41) 在MapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber.next(Subscriber.js:54) 在XMLHttpRequest.onLoad(http.js:1070) 在ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask(zone.js:423)>
答案 0 :(得分:0)
按照@JBNizet的建议,我实现了以下可观察对象:
组件:
getPDF(){
this.apiService.getPDF(this.invoiceId)
.subscribe(
(data: Blob) => {
var file = new Blob([data], { type: 'application/pdf' })
var fileURL = URL.createObjectURL(file);
// if you want to open PDF in new tab
window.open(fileURL);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'bill.pdf';
document.body.appendChild(a);
a.click();
},
(error) => {
console.log('getPDF error: ',error);
}
);
}
服务:
getPDF(invoiceId : number): Observable<Blob>
{
this.url = this.main_url + '/invoices/generatepdf/'+invoiceId;
var authorization = 'Bearer '+sessionStorage.getItem("access_token");
const headers = new HttpHeaders({ 'Content-Type': 'application/json',
"Authorization": authorization, responseType : 'blob'});
return this.httpClient.get<Blob>(this.url, { headers : headers,responseType :
'blob' as 'json'});
}
我引用的URL: