0

I want to parse an excel file in "external storage" with apache POI on an android phone. I put the file in the downloads folder when I downloaded it. I can always expect it to be there, not on a cloud, not being edited by other apps, not ephemeral in any way. The Apache POI workbookfactory needs a FileInputStream. After trying many different things I am burnt out.

Other similar questions on here involve huge swaths of code that deal in images and fanciful sources. All the examples I find use startActivityForResult which is DEPRECATED. So I tried some registerForActivityResult using contracts. No dice. Anyone know why the mime type "application/vnd.ms-excel.sheet.macroEnabled.12" doesn't work for xlsm files but images/png does? I also tried copying the file from content URI to local/app/scoped/cachedir storage and I wasn't successful either.

I was expecting the ability to point to a file and say "into the Apache POI excel file wood chipper with you!" and like in Fargo the Apache POI would spit little red cell values all over Log.d and eventually I'll do stuff with that information.

import android.content.ContentResolver
import android.net.Uri
import android.os.Bundle
import android.os.ParcelFileDescriptor
import android.provider.OpenableColumns
import android.util.Log
import android.widget.Button
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import org.apache.commons.compress.utils.IOUtils
import org.apache.poi.ss.usermodel.WorkbookFactory
import java.io.*
import java.nio.channels.FileChannel


fun readingxl(input: InputStream?) {

    //Workbook wb = Workbookfactory.create(new File(bob.getPath()))
    //Log.d("wtf",bob.toString())
    //val input = FileInputStream("./text.xlsm")
    //val xlWb = WorkbookFactory.create(input)
    //val input = FileInputStream(bob.getPath())

    val xlWb = WorkbookFactory.create(input)
    Log.d("wtf","b")
    //val xlWb = WorkbookFactory.create(input)
    Log.d("wtf","c")
    val xlWs = xlWb.getSheet("Daily Recording")
    Log.d("wtf","d")

    for (j in 44..50) {


        for (i in 0..11) {
            //Log.d("wtf",((("${xlWs.getRow(j).getCell(i)}, ")).toString()))
            Log.d("wtf", "${xlWs.getRow(j).getCell(i)}, ")

        }

    }
}

fun ContentResolver.getFileName(fileUri: Uri): String {

    var name = ""
    val returnCursor = this.query(fileUri, null, null, null, null)
    if (returnCursor != null) {
        val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        returnCursor.moveToFirst()
        name = returnCursor.getString(nameIndex)
        returnCursor.close()
    }

    return name
}


class MainActivity : AppCompatActivity() {

    val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        // 'ActivityResultCallback': Handle the returned Uri
        if (uri != null) {
            Log.d("wtf",uri.getPath().toString())
            val inputStream = applicationContext.contentResolver.openInputStream(uri)
            readingxl(inputStream)

            /*
            val parcelFileDescriptor = applicationContext.contentResolver.openFileDescriptor(uri, "r", null)

            parcelFileDescriptor?.let {
                val inputStream = FileInputStream(parcelFileDescriptor.fileDescriptor)
                val file = File(applicationContext.cacheDir, "text.xlsm")//applicationContext.contentResolver.getFileName(uri))
                val outputStream = FileOutputStream(file)
                IOUtils.copy(inputStream, outputStream)
            }*/


            }



        }




    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ///storage/emulated/0/Download


        var button = findViewById<Button>(R.id.button)

        button.setOnClickListener{


            //getContent.launch("*/*")
            getContent.launch("*/*")

        }

    }
}
9
  • Instead of a FileInputStream give it the InputStream you opened for the uri. Commented Feb 9, 2023 at 18:22
  • fun readingxl(input: InputStream?) { ?? FileInputStream? Commented Feb 9, 2023 at 18:23
  • "Anyone know why the mime type "application/vnd.ms-excel.sheet.macroEnabled.12" doesn't work for xlsm files" -- Android does not know about every possible MIME type. "I put the file in the downloads folder when I downloaded it" -- you will need to download it from inside your app to be able to access it in Downloads/ on Android 11+. "I also tried copying the file from content URI to local/app/scoped/cachedir storage and I wasn't successful either" -- your minimal reproducible example does not show this. FileInputStream("./text.xlsm") does not refer to a valid path, and we do not know what bob is. Commented Feb 9, 2023 at 18:29
  • @CommonsWare, Sorry Bob was a temp variable I was using when trying different "solutions" from stackoverflow and the web. Commented Feb 9, 2023 at 21:47
  • 1
    Your post is a mess, your code is a mess, you talk about a hundred things. Rewrite. Start with an uri and show how you use it. Commented Feb 10, 2023 at 4:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.