[Download locally created pdf file] How to use Webview to convert and download Blob files

I am using an html file that uses a js file to make a pdf contains tables. This files gives you a pdf to download. I try appinventor, but can not manage to download that local created pdf file. I see the download component on kodular, it gives me a hope.

But this time it gives me a blob files and saying “can only download HTTP/HTTPS” and “blob:///sdadasdasdasdas…” so it creates pdf but can not handle it.

Is it any way to download locally created files?
By the way i tried activitystart (open chrome) to download file on appinventor, and managed to download but couldnt use js files (can not reach of js file, path issuse i think) so cant get the data i need.

WebViewer (1).aia (6.3 KB)

You should provide some blocks to understand what the action transformer is

EDIT: I figure out how to save the pdf file without internet connection.
I will share aia and other files soon. need to sleep.:sweat_smile::laughing:

THE main goal is to download the locally created pdf file (No internet, no sending data to a web server, or etc).

1 html file includes 3 js file. Html file converts the JSON data to a pdf file and download it. The JS documents and commands work percetly on pc and gives us pdf to download. You can watch the gif file (ignore alerts).
pdfmaker

IN KODULAR: I load html file on webview, watch the gif to see how it works bu not gives us pdf to download. instead it gives us a blob file and we cant get it.

Belowe image is the kodular screen, html and the js file uploaded to assests.

This is the inside of html file

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Simple example</title>
</head>

<body onload="basla()">

<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.33/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.33/vfs_fonts.js"></script>

<script src="veri1.js"></script> <!--DATA COMES FROM HERE-->

Yükleniyor....


<script>
function tarihver() {
	var date = new Date();
  var monthNames = [
    "Ocak", "Şubat", "Mart",
    "Nisan", "Mayıs", "Haziran", "Temmuz",
    "Ağustos", "Eylül", "Ekim",
    "Kasım", "Aralık"
  ];

  var day = date.getDate();
  var monthIndex = date.getMonth();
  var year = date.getFullYear();

  return day + ' ' + monthNames[monthIndex] + ' ' + year;
}
function basla(){
	alert(JSON.stringify(transformedULSData) );	
	olustur();
}


// -- Make a Loan Note Register report. (This is attached to the button.)
function olustur() {
	alert("oluştur");

	let veriler = transformedULSData.map((textRow) => {
		return {
			"borrowerName": textRow.borrowerName,
			"loanNoteFirst": textRow.loanNoteFirst,
			"loanNoteLast": textRow.loanNoteLast,
			"originalPrincipal": textRow.originalPrincipal,
			"currentBalance": textRow.currentBalance,
			"borrowerRate": textRow.borrowerRate,
			"term": textRow.term,
			"drawdown": textRow.drawdown,
			"payments": textRow.payments,
			"status": textRow.status
		}
	});
	alert("veriler oluşturuldu");


	const makeCell = (content, rowIndex = -1, options = {}) => {
		return Object.assign({text: content, fillColor: rowIndex % 2 ? 'white' : '#e8e8e8'}, options);
	}

	// -- Format the table cells for presentation.
	const thl = (content, rowIndex = -1, options = {}) => {
		return makeCell(content, rowIndex, Object.assign({ bold: true, alignment: 'left', fontSize: 6 }, options));
	}
	const thr = (content, rowIndex = -1, options = {}) => {
		return makeCell(content, rowIndex, Object.assign({ bold: true, alignment: 'right', fontSize: 6 }, options));
	}
	const tdl = (content, rowIndex = -1, options = {}) => {
		return makeCell( content, rowIndex, Object.assign({ bold: false, alignment: 'left', fontSize: 6 }, options));
	}
	const tdr = (content, rowIndex = -1, options = {}) => {
		return makeCell( content, rowIndex,Object.assign({ bold: false, alignment: 'right', fontSize: 6 }, options));
	}
	const tds = (content, rowIndex = -1, options = {}) => {
		return makeCell( content, rowIndex,Object.assign({ bold: false, alignment: 'justify', fontSize: 6 }, options));
	}

	const truncateContent = (content, maxLength = 17) => {
		return ''.concat(content.slice(0, maxLength), content.length > maxLength ? '…' : '');
	}



	// -- Create a base document template for the reports.
	const createDocumentDefinition = (reportDate, subHeading, ...contentParts) => {
		const baseDocDefinition = {
			pageSize: 'A4',
			footer: (currentPage, pageCount) => {
				return {
					text: `${reportDate} : Sayfa ${currentPage.toString()} of ${pageCount.toString()}`,
					alignment: 'center',
					fontSize: 7
				}
			},

			styles: {
				title: {
					fontSize: 24
				},
				titleSub: {
					fontSize: 18
				},
				titleDate: {
					fontSize: 14,
					alignment: 'right',
					bold: true
				}
			},

			content: [
				{
					columns: [
						{text: 'Proses Takip', style: 'title', width: '*'},
						{text: tarihver(), style: 'titleDate', width: '160'},
					]
				},
				{text: `${subHeading}\n\n`, style: 'titleSub'}
			],			
				pageOrientation: 'landscape',
		};
		const docDefinition = JSON.parse(JSON.stringify(baseDocDefinition));
		docDefinition.footer = baseDocDefinition.footer;
		docDefinition.content.push(...contentParts);
		return docDefinition;
	};







    // -- Table summary
    const tableSummary = {
        table: {
            widths: ['*', 70],
            body: [
                [{text: tarihver(), bold: true}, tdr("deneme metin", 'white')]
            ]
        }
    };

    // -- Generate the body of the document table, with headings
    const tableBody = (dataRows) => {
        const body = [
            [
                thl('Sira no'),
				thl('ÜRÜN'),
				thl('RESİM NO'),
				thl('DAMGA ARMA'),
				thl('ÜRETİM EMRİ'),
				thl('PARTİ NO'),
				thl('KALİTE'),
				thl('KALINLIK'),
				thl('OPERASYON ADI'),
				thl('SAYAC'),
				thl('TEZGAH KOD'),
				thl('OP.SÜRESİ'),
				thl('OPERATÖR'),
				thl('SAAT'),
				thl('HATA KODU'),
				thl('TEMİZLİK'),
				thl('DÖF NO.'),
				thl('DEĞERLENDİRME/SONUÇ'),
            ]
        ]
        dataRows.forEach((row, index) => {
            const tableRow = []
            tableRow.push(tdl(row['borrowerName'], index))
            tableRow.push(tdl(row['loanNoteFirst'], index))
            tableRow.push(tdl(row['loanNoteLast'], index))
            tableRow.push(tdl(row['originalPrincipal'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            tableRow.push(tdl(row['currentBalance'], index))
            body.push(tableRow)
        })
        return body
    }

    // -- The main report table, with the table body.
    const tableData = {
        table: {
            headerRows: 1,
            //widths: [50, '*', 70, 70, 70],

            body: tableBody(veriler),
        }
    };
	alert("kayıt öncesi 1");
    const docDefinition = createDocumentDefinition(tarihver(), 'Loan Note Register', tableSummary, ' ', tableData);
    alert("kayıt öncesi 2");
	pdfMake.createPdf(docDefinition).download(`loanNoteRegister-${tarihver()}.pdf`)
    //pdfMake.createPdf(docDefinition).open();
	alert("bitti");
}

</script>
</body>
</html>

I should mention about the “my appinventor startactivity attempts”. This is the screen on MIT appinventor: open html file on chrome browser and make it to download file. it works, but only when I include JSON data in the HTML file or load it from web (not local). Like this;

<script src="http://www.aaaa.com/veri1.js"></script> <!--DATA COMES FROM HERE-->

This is the MIT App blocks
001436

Below gif show us the first attemp use local JS file (not working, probably can not load js file), second attempt shows us load js file from web server (working and download the pdf).

This is the appinventor file if u interested
pdf_create_and_download.aia (5.2 KB)

NOW WHAT SHOULD I DO,
WE ARE GOING TO USE THİS APP ON AN NONE-INTERNET CONNECTION AREA. SO WE CANT USE INTERNET OR WEB SERVERS.

CAN SOMEONE HELP ME PLEASE

I recommended to don’t use caps (uppercase letters) because it looks like shouting to someone :sweat_smile:

Maybe I can’t give exactly solution, but I found some things you may try:

  1. Asset folder is different if you are using Companion. Another folder for in production, another folder in companion.

  2. You didn’t set any URL to Download component, so it won’t download anything.

  3. Also as you see, Kodular’s WebView can only download HTTPS/HTTP URL’s. So looks like it is not possible to download from local asset.

Also maybe you can use another way to create PDF because looks like you are using HTML —> JS ----> PDF way.

Also, I think Taifun’s snippets can help you:

https://puravidaapps.com/snippets.php#2htmlread

If not, you can look for extensions and other stuff in same page.

2 Likes

So what I do is I use the FileRead function read the html file, and then use the Webviewer with the text response. I generate the html dynamically for each session and it is done on the phone. I did it like this because as @yusufcihan said there are some issues with loading local files via WebViewer. I have a bug out about it and have not gotten the answer.

I am interested in the jscript to create the PDF on the phone. So I will try to help you with that.

One of the things you can do is merge the jscript into the html in the app, save the file, then do a read and send the entire text as a string to the Web Viewer.

1 Like

i actually try that. Tinyfy the html and js files, assigned them to the variable, and then save them in the file. but none of appinventor, kodular, thunkable can manage such long code :smiley:

Anyway, i made the app in my style. i put html and js files to the root folder of device (storage/emulated/0/). There is 3 file by the way. plus i create a json text and save it as js to the same location. Totally 4 files i use.

First of all i save the js file. Than fire the html with activitystarter. it create and downloads the pdf file now. You can see the files on device.

There are still some problems, after the starting browser, i can not turn back with back button on phone. Every time i need to kill process. is there a way to do this. Here gif.

You can download tha aia file and import to kodular or somewhere else. maybe someone can do better, i hope :smiley: thanks for your replays by the way.

islemtakip.aia (21.9 KB)
processtakip.zip (890.9 KB)

Thanks for the detailed response. Let me look into it. I cant look at it until later tomorrow. But I will look into it.

With the file not going back on the backbutton make sure you use these two blocks to control and get the information you need.

Best Regards.

2 Likes

i couldnt manage the backpress thing :stuck_out_tongue:
but i made the program much good looking, and add some stuff. After saving the pdf with browser its still going on not to go back to application from browser.
Do not forget to put html and js file (zipfiles) to device root folder.

have a nica day.

Last apk and aia file here
islem_takip_2.aia (52.0 KB)
islem_takip_2.apk (5.1 MB)
processtakip.zip (890.9 KB)

Can we use dompdf or jspdf to create pdf file from html code

I used pdfmake.js library. You can use jspdf or other stuff to create pdf. U should try it.