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("*/*")
}
}
}
fun readingxl(input: InputStream?) {?? FileInputStream?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 whatbobis.