我是phonegap的新手,也是棱角分明的新手,所以请假设我什么都不知道,并提供完整的答案。你如何在Angular 5项目中使用phonegap插件?
我创建了一个使用.net核心web api后端的角度网站,它可以在phonegap中运行 - 但是我需要使用插件,特别是FileWriter。我的应用程序需要做的一件事是生成一个PDF服务器端并将其作为文件传回客户端 - 这需要保存到手机/在手机上打开。我的webapi方法返回一个FileContentResult。在该页面的角度ts文件中,我使用名为filesaver的npm库,并且在成功请求获取所述pdf文件时,我会将返回的结果粘贴到blob中并使用filesaver saveAs方法弹出文件保存对话框。 ..这在桌面网络浏览器上运行良好,但是当我在我的Android手机上的phonegap开发应用程序中运行它时,它不起作用。
因此,经过一些挖掘后,我想我需要使用一个在运行时注入的phonegap插件。
我的问题是我不知道该怎么做。到目前为止我在角度应用程序中使用的所有插件都是使用npm下载的,然后我可以在ts文件中引用一个物理库...例如:
import { DataService } from '../shared/dataService'
import { Component, OnInit } from "@angular/core";
import { saveAs } from 'file-saver/FileSaver'
...
然后当我调用我的web api方法时,我可以像这样引用saveAs:
this.data.generatePdf(myParam).subscribe(data => {
let fileName = "portfolioValuation.pdf";
var blob = new Blob([data], { type: 'application/pdf' });
saveAs(blob, fileName);
}
我假设导入了解这些方法和库,因为它们位于node_modules文件夹中 - 我不记得了,但我认为我在某些时候告诉了有关node_module文件夹的角度 - 或者它只是内置为angular,因为你安装它使用npm ??
无论如何,phonegap插件似乎在运行时生成,因此我没有在node_modules文件夹中生成它们。相反,它们在我的phonegap项目文件夹的plugins文件夹中,因此我无法引用它们 - 然后angular不知道它们 - 所以它用红色强调它并且我认为它不会构建。
那么如何在我的ts文件中使用这些phonegap插件呢?特别是文件编写器 - 因为我正在谈论文件编写器这是我需要的插件,以便将我返回的文件保存到手机上?我想要的是允许移动用户点击按钮并能够打开返回的pdf。
非常感谢您的帮助
我无法得到这种确切的工作方法,所以我已经解决了这个问题。我可能已经接近我最初的尝试,所以我会分享它,以防它有帮助 - 但我也会分享我的工作。
所以我的.net核心web api方法返回了一个文件内容结果,如下所示:
return File(pdfBuffer, "application/pdf", fileName);
pdfBuffer是一个byte [],后跟MIME类型和文件名。
在我的dataService ts文件中,我正在调用此方法,如下所示:
public generatePdf(param1) {
let body = {
"param1": param1
};
let pdfOptions = new RequestOptions();
pdfOptions.headers = this.options.headers;
pdfOptions.responseType = ResponseContentType.Blob;
return this.http.post("https://myWebsite/api/GeneratePdf", body, pdfOptions)
.map((res: Response) => res.blob());
}
我已重命名变量和方法名称等,但您可以看到我已将响应类型指定为blob并将响应映射为此类。我还复制了我正在使用的包含身份验证令牌的通用标头中的标头
我在页面ts文件中调用它后,我订阅,这是我开始遇到问题的地方...
为了让cordova能够在我的ts文件中获取,我已将以下内容添加到项目根目录下的tsconfig.json文件中:
"types": [
"cordova",
"cordova-plugin-file"
],
我还使用npm将phonegap和cordova库安装到我的项目中。
在页面的ts文件中,我在我的导入下添加了以下变量,因此我可以选择注入的cordova库:
declare var window: any;
declare var LocalFileSystem: any;
declare var device: any;
var storageLocation = "";
declare var cordova: any;
然后这个方法保存或显示blob为pdf:
public generatePdf() {
let param1= param1Logic;
$("#waitingAnimation").show();
this.data.generatePdf(param1).subscribe(data => {
let fileName = "myDocument.pdf";
var blob = new Blob([data], { type: 'application/pdf' });
$("#waitingAnimation").hide();
//I tried to just open the pdf on the device like so... just get a blank white page on phonegap
//var fileURL = URL.createObjectURL(blob);
//window.open(fileURL); // if you want to open it in new tab
switch (device.platform) {
case "Android":
storageLocation = 'file:///storage/emulated/0/';
break;
case "iOS":
storageLocation = cordova.file.documentsDirectory;
break;
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
console.log('file system open: ' + fs.name);
let parentEntry = storageLocation + "Download/" + fileName;
fs.root.getFile(parentEntry, { create: true, exclusive: false }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
console.log('create writer');
fileWriter.onerror = function (e) {
console.log("Failed file write: " + e.toString());
};
fileWriter.write(blob);
});
}, null);
}, null);
});
}
这可能不是确切的代码 - 我在没有保存到存储库的情况下做了很多修改 - 所以我只是把它放在我在代码中留下的评论中。我没有得到任何控制台错误 - 它只是没有做任何事情。
我认为它与响应是blob有关,与白名单有关。我开始阅读它,发现它有安全隐患,我找不到任何描述如何使其安全的内容,所以此时我开始考虑其他解决方案。
所以我的工作......
我以为我会尝试从另一个旧的aspx网站获取一个pdf,只需要一个简单的获取请求到这个ashx页面,它只返回一个pdf MIME类型的pdf文件。我可以用angular调用它,并使用以下代码在浏览器中打开pdf:
window.open("https://myWebsite.ashx?fileName=" + fileName, '_system', 'location=no');
所以我所做的就是改变我的Web API来解决这个问题。
而不是使用帖子来回复blob,而是将该帖子发送到服务器创建一个pdf,它存储在服务器上的临时目录中 - 这个post方法用一些带有文件名的JSON响应。
然后我创建了另一个Web API方法,它接受带有文件名作为参数的get请求(查询字符串),这会查找该临时文件(我知道服务器位置,只是附加提供的文件名) - 如果文件存在我回复与之前的FileContentResult一样,从临时存储中删除文件。像这样:
[HttpGet]
[DeleteFileAttribute]
public IActionResult Get(string fileName)
{
var tempPath = $"serverLocationGoesHere/{fileName}";
byte[] fileBytes = System.IO.File.ReadAllBytes(tempPath);
return File(fileBytes, "application/pdf", fileName);
}
DeleteFileAttribute是我删除文件的自定义属性。
所以现在在我的dataService ts文件中,我调用初始的GeneratePdf post方法来生成pdf:
public generatePdf(param1) {
let body = {
"param1": param1
};
return this.http.post("https://myWebSite/api/GeneratePdf", body, this.options)
.map((res: Response) => {
return res.json();
});
}
如你所见,这只是返回JSON ...
所以在我的页面ts文件中,我需要做的就是:
public generatePdf() {
let param1 = param1Logic;
$("#waitingAnimation").show();
this.data.generatePdf(param1).subscribe(data => {
let fileName = data.fileName;
$("#waitingAnimation").hide();
window.open("https://myWebsSite/api/DownloadFile?fileName=" + fileName, '_system', 'location=no');
}
现在我可以在我的phonegap应用程序中打开服务器生成的PDF - 虽然不是我想要的方式。我确信有更好的方法可以使用一些库打开Pdf - 但希望这里有人有用的东西!