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 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入