使用 Volley Library 从 API 下载 Excel 文件

问题描述 投票:0回答:1

我正在尝试使用 Volley(Android Kotlin)从 API 下载 Excel 文件

我的代码:

val requestBody = ""
val stringReq: StringRequest =
    object : StringRequest(
        Method.GET, url,
        com.android.volley.Response.Listener { response ->
            hidePregressBar()

            Log.d("API Response",""+response)
        },
        com.android.volley.Response.ErrorListener { error ->
            hidePregressBar()
        }
    )

以下是从 API 获得的响应。如何将其转换为Excel文件?

PK��$��O������������������������������xl/worksheets/sheet1.xml��ێ�F�� C��-̠۫U�"�h�M�h�h�F
D: >���ڞ�r3������s!��|��s���T�u��wY&*��������'�:u�i��Rnݟ�v��~�\�~��R6N+P�[��4�����(��^�J�핽�Eܴ���Օ�q�
D: ��>�8+�^a�!j����TȲ�E��㦍_���P+��\�%Z�j߬UJm�ē�Dv��,P�@�~?UO�dզx�����22�{��z�x21n3��}.��+"��������"�����!��"�}/���(0Cdx��6���m�� ��͏�U{��g���ߙ�ԓc��6}S��v�-ݺ�k���_;���INu���dv86�:�N*��)o^T�O�6ǶFV��wu1�tթ'*�����ǜ�Yٿ�����_�
D: ��G�a$0��#x��@|:B�bF0[!��f�Ħ������(n��F���o������V��ڛW�����x������w�4�x�;�yG�w�I6^��L��!]3��/V�`}��M��/�^��W�Ir?6�<�3��%�<_�������'���D�$"�D�o%"˻B>�@��~j2�Y���2ò��nf.̸��F�[�,{��p���%\�,Q���>w��.�B��"f."���tY"����ß�P�gh�Y�h�ܱ�<��܊[�<�L���h�ܱ7�< ߌ=#�cU��rGz|� lKcKzY�����q��-m=���J4T�H�[��-m��U�У�F�j#fK[�lU"�h�Ѹ�(���
D: �*z��h\b�mikm�J�-.7�k��Dz(m�}�������Q�"Y~������ڈ���H���B9�Q���m���P2JC�`(%��d0���!P2J�@�(%C����!P2J�B�P(
D: %C�d(����P2J�B�P(%àd���aP2J�A�0(%àdB(�J&��   �dB(�J&��   �dB(�J�C�p(%ád8����P2J�C�p(%#�d����P2JF@(%#�d���h��ח���揪���뿆�=և���7մ�[��t�J5R��n�2N�I.�M��:�w�U
D: ���z�T9Jg�l�_6�n�i�ĕ���:�d����,ݺ�[ڇ5?���PK<�r�����������PK��$��O������������������������#������xl/worksheets/_rels/sheet1.xml.rels��M��0������Y���t[�[���m,��޾^t`
D: ]�RO����,��q�)x��@���M~0p�7[P��;��gwط͉g��F�)�*�c�q�(v�D�Ⱦl���eLF�?���_�S��tt5���?v����!���>�y�.�Z����ـֿ���EF��Lj]|������PK�j�������3����PK��$��O������������������������!������xl/drawings/worksheetdrawing1.xml��]n�0��U�iZC^�N0�%n�����~�J6i{m�?���nt��Db|#�z��]#�o��(8��`��F\��n��5�ϼ�"�{^��}��ZJV=:�2�Ӵ
D: � ��:�   �IvVΫ�E��{ĸ�&�������Mׄ�5
D: �A��8!�b��f଩�Q=P���3��6�*��)�HB�<    8����R���_���O�,�Czȇ�&^��eFwh��ȸ8��ݱ*�6�(+l�^ޭ̳"�_PKbi���������PK��$��O������������������������������docProps/app.xml�RAn�0|A� �SJ��0(��"�5`'=o��E�"   �V���R2��
D: z�m83��+Ld��E�*E�ބ��C-��_n>��|.x��  I��wj�B���� �j�1ǵ�d:�VY�YiC��1dh[k�!�_=z��ey'���ln�(Ή��7�   f�G��S�yZmB���V;7Y�-8B%_    ��0�{6�V�4R�ǤZ�,x�#����V�mgv�.'�#����\� ^z/����ɐ��Q.E2����쐾�[H�����s�J\t܍��7�����j�=�}x���yvפ�u���_��v!�cn����t��̞�����8���fM
D: Z.>
D: :%/���|�]]ݭ��e9fN��5���PK���k���������PK��$��O������������������������������docProps/core.xml���n�0��`�@zm����&n�j&K�ewM9h3Z��y�T������ے-����:��ф�hJ��9zݬ�9����u�!G8�(�2a�h,<�ƀ�\D�1ar���0��؁�.  �a�X�}x�[l���[�BfX��%���،FtR�bT���A)0Ԡ@{�iB���*ws��\�J���M�����l�6i�
D: �)~_?�[���J��*�S&,pe�8���*&��ǔ�$ݐ9#)��>2�g}/<>7�X�Ø�G�plm׳c��K͝_��$��&Ʋ����m�,�^�=�a����PK�V}�6����l����PK��$��O������������������������������xl/theme/theme1.xml�Yˎ�6�����D�-�1�'�3i3��I�,i��S�@R3c�d�M�i�M��(�h���cHЦQ�a���$m�>���X$Ͻ<��<W�\�rp��4�Z�K�P����'a׺s2�k[����u�9�֕��.�}�i��}ص"!�}����MQ"Ǧ��P�&��3�6&v�q�vqbU��u��t�}4�~�D�N"PH�<�)�@c��f'9A�`AuDPn����c��Z�`V���r!��S|,p
D: Iג�� :�}p�^a�Ͷ���Y��c�$7,p����������F�Qs���@ߗ+�m`�~�?�*�*/
android kotlin android-volley
1个回答
0
投票

理解回应

您从 API 收到的响应是一个 ZIP 文件,其中包含 Excel 文件 (XLSX) 的组件。这是将复杂文档传输到网络的常见方法。开头的字符“PK”表明 ZIP 格式,并且提及“xl/worksheets”、“xl/theme”,表示 Excel 文件的内部结构。

转换过程:我的解决方案

  1. 获取字节数组:
  • Volley 提供的响应为
    String
    。将这个
    String
    转换为
    ByteArray
    。这是 ZIP 文件的原始数据。
  • 使用类似
    response.toByteArray(Charset.forName("UTF-8"))
    的方法进行转换。
  1. 临时 ZIP 文件:
  • 使用
    File.createTempFile
    在您的设备上创建一个临时文件,并在其中写入
    ByteArray
    。这将保存您从 API 获取的 ZIP 文件。
  1. 提取 Excel 文件:
  • 使用ZIP提取库,我使用
    java.util.zip.ZipInputStream
    打开临时ZIP文件。
  • 遍历 ZIP 中的条目。找到扩展名为“.xlsx”的文件。
  • 将“.xlsx”文件解压到临时文件中。
  1. 打开文件:
  • 使用具有
    ACTION_VIEW
    操作的 Intent 和正确的 MIME 类型 (
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    ),使用兼容的应用程序(如 Microsoft Excel、Google Sheets)打开提取的 Excel 文件,我使用 Microsoft。

val stringReq: StringRequest = object : StringRequest(
    Method.GET, url,
    { response ->
        hidePregressBar()
        
        // 1. get byte array
        val zipData = response.toByteArray(Charset.forName("UTF-8"))

        // 2. temp ZIP file
        val tempZipFile = File.createTempFile("temp_excel", ".zip", context?.cacheDir)
        tempZipFile.writeBytes(zipData)

        // 3. extract excel file
        val zis = ZipInputStream(FileInputStream(tempZipFile))
        var entry: ZipEntry? = zis.nextEntry
        while (entry != null) {
            if (entry.name.endsWith(".xlsx")) {
                val tempXlsxFile = File.createTempFile("extracted_excel", ".xlsx", context?.cacheDir)
                FileOutputStream(tempXlsxFile).use { fos ->
                    zis.copyTo(fos)
                }

                // 4. open file
                val intent = Intent(Intent.ACTION_VIEW).apply {
                    setDataAndType(Uri.fromFile(tempXlsxFile), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                }
                startActivity(intent)
                break // exit loop after extracting file
            }
            entry = zis.nextEntry
        }
        zis.close()

        // cleanup delete temp files
        tempZipFile.delete()
    },
    { error ->
        hidePregressBar()
        // errors
    }
) {
    // ... requests
}

  • 错误处理:确保在 Volley 请求中包含网络故障、错误文件格式的错误处理
  • 权限:如果您将文件保存到外部存储,请确保您拥有
    WRITE_EXTERNAL_STORAGE
    权限。
  • 安全性:在保存或执行 API 之前,始终验证和清理来自 API 的数据。

© www.soinside.com 2019 - 2024. All rights reserved.