doujieju0397 2019-05-15 04:37 采纳率: 0%
浏览 141
已采纳

如何使用FPDF和Retrofit库发送PDF生成的特定参数并将其下载到Android中

I want to send the variable parameter key from Android to FPDF variable in API Server which will generate a set of report based on date range, but the variable in FPDF API wasn't receiving the Android's variable sent.
How to do this? Which Call<> should I use?

I already tried to use Call<ResponseBody> in order to sent the parameter. I am also tried to test it if the connection to the targeted file is success below onResponse and it response true.
But, when the time come for downloading the file into the device I tried to target the download link straightly to the file path in the server.
But after opening the downloaded file what I get is a blank data table which explain that the variable in the FPDF didn't receive the Android variable sent.

Here are my downloadPDF() method, to send the parameter to 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();
            }
        });
    }

Interface method:

    @FormUrlEncoded
    @POST("somepath/get_print.php")
    Call<ResponseBody> getPrint(
            @Field("keyDateFrom") String from,
            @Field("keyDateTo") String to
    );

downloadManager() method:

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);
    }

And my get_print.php script:

<?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();
?>

I mean, how to make the variable in FPDF API receiving the value from Android, so Android can download the generated file according to the query?
I already tried to do this on Postman it returns a right formatted PDF, but not in Android.

How to do it? What's the alternate? Appreciate any helps.

  • 写回答

1条回答 默认 最新

  • doumi1944 2019-05-17 03:28
    关注

    I am succeeded to retrieve the PDF file from the endpoint PDF table generated which is using 2 variable sent from Android as expected.

    I am using these method as a request

    downloadPDF()

        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();
                }
            });
    

    Interface method:

        @FormUrlEncoded
        @POST("somepath/your_file.php")
        Call<ResponseBody> getPrint(
                @Field("keyDateFrom") String from,
                @Field("keyDateTo") String to
        );
    

    And the writeResponseBodyToDisk(ResponseBody body) to write the response into the PDF + saving it into the device

    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;
            }
        }
    

    Hopes my confusion helps someone outhere :P

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 cplex运行后参数报错是为什么
  • ¥15 之前不小心删了pycharm的文件,后面重新安装之后软件打不开了
  • ¥15 vue3获取动态宽度,刷新后动态宽度值为0
  • ¥15 升腾威讯云桌面V2.0.0摄像头问题
  • ¥15 关于Python的会计设计
  • ¥15 聚类分析 设计k-均值算法分类器,对一组二维模式向量进行分类。
  • ¥15 stm32c8t6工程,使用hal库
  • ¥15 找能接spark如图片的,可议价
  • ¥15 关于#单片机#的问题,请各位专家解答!
  • ¥15 博通raid 的写入速度很高也很低