如何使用 FPDF 和 Retrofit 库发送用于生成 PDF 的特定参数并将其下载到 Android
How to send a specific parameter for PDF generation using FPDF and Retrofit library and download it into Android
我想将 Android 中的可变参数键发送到 API 服务器中的 FPDF 变量,这将根据日期范围生成一组报告,但是 FPDF 中的变量 API 没有收到 Android 发送的变量。
这该怎么做?我应该使用哪个 Call<>
?
我已经尝试使用 Call<ResponseBody>
来发送参数。我还尝试测试它是否在 onResponse
以下成功连接到目标文件并且它响应为真。
但是,当需要将文件下载到设备中时,我尝试将下载 link 直接定位到服务器中的文件路径。
但是在打开下载的文件后,我得到的是空白数据 table,这说明 FPDF 中的变量没有收到发送的 Android 变量。
这是我的 downloadPDF() 方法,用于将参数发送到 FPDF API:
private void downloadPDF() {
RestApi api = RetroFit.getInstanceRetrofit();
Call<ResponseBody> printCall = api.getPrint(
strDateFrom,
strDateTo
);
printCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
downloadManager();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "No data :(", Toast.LENGTH_SHORT).show();
}
});
}
接口方法:
@FormUrlEncoded
@POST("somepath/get_print.php")
Call<ResponseBody> getPrint(
@Field("keyDateFrom") String from,
@Field("keyDateTo") String to
);
downloadManager()方法:
private void downloadManager() {
DownloadManager downloadService = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://someweb.com/somefolder/get_print.php");
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
还有我的get_print.php脚本:
<?php
include 'config.php';
$keyDateFrom = $_POST["keyDateFrom"];
$keyDateTo = $_POST["keyDateTo"];
require('fpdf.php');
$pdf = new FPDF('P','mm','A4');
$pdf->AddPage();
$pdf->Image('logo_hsp_transparan.png',10,10,30,15);
$pdf->SetLeftMargin(20);
$pdf->SetFont('Arial','B',16);
$pdf->Cell(190,7,'Daftar Peminjaman Kendaraan HSPnet',0,1,'C');
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7,'Jl. Tanah Merdeka No.1, RT.10/RW.3, Rambutan, Ciracas, Kota Jakarta Timur',0,1,'C');
$pdf->Cell(10,7,'',0,1);
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7, $keyDateFrom ,0,1,'C');
$pdf->SetFont('Arial','',9);
$pdf->Cell(190,7,'to',0,1,'C');
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7, $keyDateTo ,0,1,'C');
$pdf->SetLeftMargin(32);
$pdf->SetFont('Arial','B',8);
$pdf->Cell(10,7,'',0,1,'C');
$pdf->Cell(6,6,'NO',1,0,'C');
$pdf->Cell(35,6,'TUJUAN',1,0,'C');
$pdf->Cell(23,6,'PEMINJAM',1,0,'C');
$pdf->Cell(35,6,'KENDARAAN',1,0,'C');
$pdf->Cell(28,6,'JAM BERANGKAT',1,0,'C');
$pdf->Cell(28,6,'JAM PULANG',1,1,'C');
$pdf->SetFont('Arial','',8);
$query = mysqli_query($link,
"SELECT some_column
FROM `SOME_TABLE`
WHERE (DATE(some_column) BETWEEN '$keyDateFrom' AND '$keyDateTo')");
$i = 1;
while ($row = mysqli_fetch_array($query)){
$pdf->Cell(6,6,$i++,1,0,'C');
$pdf->Cell(35,6,$row['some_column'],1,0);
}
$pdf->Output();
?>
我的意思是,如何让FPDF中的变量API接收到Android的值,这样Android就可以根据查询下载生成的文件了?
我已经尝试在 Postman 上执行此操作 returns 格式正确的 PDF,但在 Android 中不行。
怎么做?什么是替代品?感谢任何帮助。
我成功地从生成的端点 PDF table 检索了 PDF 文件,该文件按预期使用了从 Android 发送的 2 个变量。
我正在使用这些方法作为请求
下载PDF()
private void downloadPDF() {
RestApi api = RetroFit.getInstanceRetrofit();
Call<ResponseBody> printCall = api.getPrint(
strDateFrom,
strDateTo
);
printCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
Toast.makeText(getContext(), "server contacted and has file", Toast.LENGTH_SHORT).show();
// The most important part is in below code
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
Toast.makeText(getContext(), "file download was a success? " + writtenToDisk, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Server contact failed ", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "No connection", Toast.LENGTH_SHORT).show();
}
});
接口方法:
@FormUrlEncoded
@POST("somepath/your_file.php")
Call<ResponseBody> getPrint(
@Field("keyDateFrom") String from,
@Field("keyDateTo") String to
);
然后 writeResponseBodyToDisk(ResponseBody body) 将响应写入 PDF + 将其保存到设备中
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
File futureStudioIconFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"yourFileName.pdf");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d("TAG", "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
希望我的困惑能对外面的人有所帮助 :P
我想将 Android 中的可变参数键发送到 API 服务器中的 FPDF 变量,这将根据日期范围生成一组报告,但是 FPDF 中的变量 API 没有收到 Android 发送的变量。
这该怎么做?我应该使用哪个 Call<>
?
我已经尝试使用 Call<ResponseBody>
来发送参数。我还尝试测试它是否在 onResponse
以下成功连接到目标文件并且它响应为真。
但是,当需要将文件下载到设备中时,我尝试将下载 link 直接定位到服务器中的文件路径。
但是在打开下载的文件后,我得到的是空白数据 table,这说明 FPDF 中的变量没有收到发送的 Android 变量。
这是我的 downloadPDF() 方法,用于将参数发送到 FPDF API:
private void downloadPDF() {
RestApi api = RetroFit.getInstanceRetrofit();
Call<ResponseBody> printCall = api.getPrint(
strDateFrom,
strDateTo
);
printCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
downloadManager();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "No data :(", Toast.LENGTH_SHORT).show();
}
});
}
接口方法:
@FormUrlEncoded
@POST("somepath/get_print.php")
Call<ResponseBody> getPrint(
@Field("keyDateFrom") String from,
@Field("keyDateTo") String to
);
downloadManager()方法:
private void downloadManager() {
DownloadManager downloadService = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://someweb.com/somefolder/get_print.php");
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
还有我的get_print.php脚本:
<?php
include 'config.php';
$keyDateFrom = $_POST["keyDateFrom"];
$keyDateTo = $_POST["keyDateTo"];
require('fpdf.php');
$pdf = new FPDF('P','mm','A4');
$pdf->AddPage();
$pdf->Image('logo_hsp_transparan.png',10,10,30,15);
$pdf->SetLeftMargin(20);
$pdf->SetFont('Arial','B',16);
$pdf->Cell(190,7,'Daftar Peminjaman Kendaraan HSPnet',0,1,'C');
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7,'Jl. Tanah Merdeka No.1, RT.10/RW.3, Rambutan, Ciracas, Kota Jakarta Timur',0,1,'C');
$pdf->Cell(10,7,'',0,1);
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7, $keyDateFrom ,0,1,'C');
$pdf->SetFont('Arial','',9);
$pdf->Cell(190,7,'to',0,1,'C');
$pdf->SetFont('Arial','B',9);
$pdf->Cell(190,7, $keyDateTo ,0,1,'C');
$pdf->SetLeftMargin(32);
$pdf->SetFont('Arial','B',8);
$pdf->Cell(10,7,'',0,1,'C');
$pdf->Cell(6,6,'NO',1,0,'C');
$pdf->Cell(35,6,'TUJUAN',1,0,'C');
$pdf->Cell(23,6,'PEMINJAM',1,0,'C');
$pdf->Cell(35,6,'KENDARAAN',1,0,'C');
$pdf->Cell(28,6,'JAM BERANGKAT',1,0,'C');
$pdf->Cell(28,6,'JAM PULANG',1,1,'C');
$pdf->SetFont('Arial','',8);
$query = mysqli_query($link,
"SELECT some_column
FROM `SOME_TABLE`
WHERE (DATE(some_column) BETWEEN '$keyDateFrom' AND '$keyDateTo')");
$i = 1;
while ($row = mysqli_fetch_array($query)){
$pdf->Cell(6,6,$i++,1,0,'C');
$pdf->Cell(35,6,$row['some_column'],1,0);
}
$pdf->Output();
?>
我的意思是,如何让FPDF中的变量API接收到Android的值,这样Android就可以根据查询下载生成的文件了?
我已经尝试在 Postman 上执行此操作 returns 格式正确的 PDF,但在 Android 中不行。
怎么做?什么是替代品?感谢任何帮助。
我成功地从生成的端点 PDF table 检索了 PDF 文件,该文件按预期使用了从 Android 发送的 2 个变量。
我正在使用这些方法作为请求
下载PDF()
private void downloadPDF() {
RestApi api = RetroFit.getInstanceRetrofit();
Call<ResponseBody> printCall = api.getPrint(
strDateFrom,
strDateTo
);
printCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
Toast.makeText(getContext(), "server contacted and has file", Toast.LENGTH_SHORT).show();
// The most important part is in below code
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
Toast.makeText(getContext(), "file download was a success? " + writtenToDisk, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Server contact failed ", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "No connection", Toast.LENGTH_SHORT).show();
}
});
接口方法:
@FormUrlEncoded
@POST("somepath/your_file.php")
Call<ResponseBody> getPrint(
@Field("keyDateFrom") String from,
@Field("keyDateTo") String to
);
然后 writeResponseBodyToDisk(ResponseBody body) 将响应写入 PDF + 将其保存到设备中
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
File futureStudioIconFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"yourFileName.pdf");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d("TAG", "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
希望我的困惑能对外面的人有所帮助 :P