Reputation: 71
I am working in a project where I have to show certificate that the user finished a course, there is an URL of the API that uses the get method within a token to have acces to a pdf file, the problem is that I do not know how to show or transform that response into a pdf, using flutter, I tried to use the url_launcher dependency because in the browser shows the pdf normally, but the problem is that it I need to pass a token to that url. the second thing that i tried was to fetched the response of the api and save it in a temporal file and use flutter_pdfview dependency but it shows errors. this is how the response of the api looks like:
%PDF-1.4
1 0 obj
<<
/Title (þÿ)
/Creator (þÿ)
/Producer (þÿQt 5.5.1)
/CreationDate (D:20211120205047)
>>
endobj
2 0 obj
<<
/Type /Catalog
/Pages 3 0 R
>>
endobj
4 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
this is what I tried:
Future LoadPDF(APIurl)async {
Map<String,String> Headers={
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': 'Bearer $userToken'
};
final response = await http.get(Uri.parse(APIurl),headers: Headers);
final bytes = response.bodyBytes;
// print(response.bodyBytes);
var dir = await getTemporaryDirectory();
File file = File(dir.path + "/data.pdf");
await file.writeAsBytes(bytes, flush: true);
setState(() {
loadDocument(file);
});
// return file;
}
Upvotes: 7
Views: 7633
Reputation: 349
Here is how I solved it:
Future<http.Response> apiCall(String fileId, String clientId) async {
String token = (await _storage.read(key: 'token')).toString();
final url = Uri.parse('$BASE_URL/oauth/notes/upload/view/$fileId/$clientId');
final headers = {"Authorization" : "Bearer $token", "Accept" : "*/*", "Accept-Encoding" : "gzip, deflate, br", "Connection": "keep-alive"};
final response = await http.get(url, headers: headers);
return response;
}
Future<File?> getContent(String fileId, String clientId, String extension) async {
//this is the api mentioned in next part
http.Response res = await api.apiCall(fileId, clientId);
dynamic response = res.bodyBytes;
if (response != null) {
final Directory? appDir = Platform.isAndroid
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
String tempPath = appDir!.path;
final String fileName =
DateTime.now().microsecondsSinceEpoch.toString() + extension;
File file = File('$tempPath/$fileName');
if (!await file.exists()) {
await file.create();
}
await file.writeAsBytes(response);
return file;
}
}
File? file = await contentService.getContent(
fileid,
id,
'.pdf');
if (file != null) {
final String? result = await openFile(file.path.toString());
if (result != null) {
print('result');
print(result);
// Warning
}
}
static Future<String?> openFile(String url) async {
final OpenResult result = await OpenFile.open(url);
}
Upvotes: 5
Reputation: 439
Hi I got the same response as you. Here I used Dio api structure. Take this as reference. Below code work fine for me.
Future<File?> downloadPDF(String applicantId, String templateId) async {
try {
final response = await dioClient.post('xxxxxx/pdfService/pdfOperation/downloadPDF', data:DownloadRequestDTO(applicantId, templateId), headers: <String, dynamic>{
'Content-Type': 'application/json'}, options: Options(responseType: ResponseType.bytes));
if (response != null) {
final Directory? appDir = Platform.isAndroid
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
String tempPath = appDir!.path;
final String fileName =
DateTime.now().microsecondsSinceEpoch.toString() + '-' + 'akt.pdf';
File file = new File('$tempPath/$fileName');
if (!await file.exists()) {
await file.create();
}
await file.writeAsBytes(response);
return file;
}
throw DownloadException('The download failed.', response);
} catch (value) {
if (value is DioError) {
print(value.response);
}
print(value.toString());
}
}
Then use open_file
package to open downloaded file
static Future<String?> openFile(String url) async {
final OpenResult result = await OpenFile.open(url);
switch (result.type) {
case ResultType.error:
return result.message;
case ResultType.fileNotFound:
return LocaleKeys.fileNotFound.tr();
case ResultType.noAppToOpen:
return LocaleKeys.noAppToOpen.tr();
case ResultType.permissionDenied:
return LocaleKeys.permissionDenied.tr();
default:
return null;
}}
And call this functions as below
Future<void> downloadAndOpenFile(BuildContext context) async {
try {
File? file = await downloadPDF('1234', 'xxxxxx');
if (file != null) {
final String? result = await openFile(file.path.toString());
if (result != null) {
// Warning
}
}
} catch (e) {
print(e);
}}
Upvotes: 3
Reputation: 206
you can use flutter_pdfview package to show pdf:
loadDocument(file) {
PDFView(
filePath: file.path,
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: false,
onRender: (_pages) {
setState(() {
pages = _pages;
isReady = true;
});
},
onError: (error) {
print(error.toString());
},
onPageError: (page, error) {
print('$page: ${error.toString()}');
},
onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController);
},
onPageChanged: (int page, int total) {
print('page change: $page/$total');
},
),
}
Upvotes: 0