# Solution about python module "tabula" runs successfully but fails in .exe Solution about python module tabula runs .py successfully and use pyinstaller to build .exe but the .exe will execute fail. Environment --- - python : 3.7 - pyinstaller : 5.9.0 - tabula-py : 2.9.0 Happens --- ### Preparation 1. `pip3 installer tabula-py` 2. `pip3 list` ![pip3list](https://hackmd.io/_uploads/ByUO_oz_6.png) ### When I want to use tabula to read pdf file: #### It can run Success : ![import](https://hackmd.io/_uploads/Hy8fujGup.png) `py -3.7 compare_BCU_RN.py` ![runSuccess](https://hackmd.io/_uploads/Hkxkiifua.png) #### and Build .exe Success : `pyinstaller -F compare_BCU_RN.py` ![buildsuccess](https://hackmd.io/_uploads/BkpPKDcdp.png) > Also don't have any warning or error in build/warn.txt and build/xerf.html #### BUT it will run FAIL ! : Run .exe (double click/power shell/cmd). ![runerror](https://hackmd.io/_uploads/SyQvKDqOa.png) Root Cause --- Module tubalu is Java base and made for running on OS(JVM). > ... *Tabula allows you to extract that data in CSV format, through a simple web interface.* ... Therefore, it does not consider supporting source code (python module source code) for being built into exe by pyinstaller. It means that it actually just uses python-command to execute Tabula-Java. > You can refer to tabula-py/tabula/io.py This is the result of the error you saw when executing exe in powershell in the previous picture. #### Official link - [OpenNews Source](https://source.opennews.org/articles/introducing-tabula/) - [Tabula Github](https://github.com/tabulapdf/tabula) - [Download from the official site](https://tabula.technology/) Solution --- :::info Notice : Just install java CANNOT fix this error. But if you want to run in python script, install and check path is fine ::: Let the .spec(pyinstaller actually build spec, refer "知呼-Pyinstaller打包通用流程" under) to pack "tabula" data file. ### General : 1. Run ```pyinstaller -F {your}.py``` 2. Modify {your}.spec : * Add ```from PyInstaller.utils.hooks import collect_data_files``` * Modify ```datas=[],```to ```datas=collect_data_files("tabula"),``` * As line 2 and 9 ![pyspec](https://hackmd.io/_uploads/r13MuE9O6.png) 3. Run ```python pyinstaller {your}.spec``` :::info Notice : Is .spec instead of .py ::: ### Practical : It will take a lot of time if you have to manually modify it every time. So you can use my .bat script: ```bat REM Build first pyinstaller -F {YOUR}.py echo MOD .spec START!! @echo off setlocal enabledelayedexpansion REM 1. copy {YOUR}.spec to {YOUR}_ori.spec copy {YOUR}.spec {YOUR}_ori.spec set "file={YOUR}.spec" REM 2. Insert "from PyInstaller.utils.hooks import" in No.2 line of {YOUR}.spec set "line_number=2" set "new_line=from PyInstaller.utils.hooks import collect_data_files" (for /f "tokens=1* delims=:" %%a in ('findstr /n "^" %file%') do ( echo.%%b if %%a equ %line_number% echo.!new_line! )) > "%file%.new" move /y "%file%.new" "%file%" echo done step 2 REM 3. Change "datas=[]" to "datas=collect_data_files(\"tabula\")" set "new_line= datas=collect_data_files("tabula")," (for /f "delims=" %%a in ('type "%file%"') do ( set "line=%%a" if "!line!"==" datas=[]," ( echo !new_line! ) else ( echo !line! ) )) > "%file%.new" move /y "%file%.new" "%file%" echo done step 3 echo MOD .spec END!! REM Build spec only again pyinstaller {YOUR}.spec ``` You just run this .bat every time after saved {your}.py, remember put it at the same folder with {your}.py. ==Error Fixed !!== If you don't want to make a new file, maybe you can try this solution : [stackoverflow-Unable to access jarfile 'tabula-1.0.2-jar-with-dependencies.jar'](https://stackoverflow.com/questions/50544515/unable-to-access-jarfile-tabula-1-0-2-jar-with-dependencies-jar) Reference --- - Solution step reference : [Github-Unable to access Jarfile](https://github.com/pyinstaller/pyinstaller/issues/5298) - pyinstaller flow reference : [知呼-Pyinstaller打包通用流程](https://zhuanlan.zhihu.com/p/165431703) ###### tags: `tabula` `python` `pyinstaller`