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 Stata链式中介效应代码修改
  • ¥15 latex投稿显示click download
  • ¥15 请问读取环境变量文件失败是什么原因?
  • ¥15 在若依框架下实现人脸识别
  • ¥15 添加组件无法加载页面,某块加载卡住
  • ¥15 网络科学导论,网络控制
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错