Last active
April 22, 2024 23:29
-
-
Save stakancheck/d5039ea7f24e86387fd4bd8f29584dff to your computer and use it in GitHub Desktop.
HtmlToPdfConvertor example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HtmlToPdfConvertor(private val context: Context) { | |
private var enableJavascript: Boolean? = null | |
// Экземпляр WebView с базовыми настройками | |
private val pdfWebView = WebView(context).apply { | |
this.settings.allowContentAccess = true | |
this.settings.allowFileAccess = true | |
this.settings.cacheMode = WebSettings.LOAD_NO_CACHE | |
} | |
fun setJavaScriptEnabled(flag: Boolean) { | |
this.enableJavascript = flag | |
} | |
@UiThread | |
fun convert( | |
pdfLocation: File, | |
htmlString: String, | |
onPdfGenerationFailed: PdfGenerationFailedCallback? = null, | |
onPdfGenerated: PdfGeneratedCallback, | |
) { | |
// Статус создания PDF | |
var pdfGenerationStarted = false | |
try { | |
// Отключаем безопасный просмотр для версий Android Oreo и выше | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
pdfWebView.settings.safeBrowsingEnabled = false | |
} | |
// Включаем JavaScript, если необходимо | |
enableJavascript?.let { pdfWebView.settings.javaScriptEnabled = it } | |
// Генерируем имя задачи для PrintAdapter | |
val jobName = Math.random().toString() | |
// Получаем атрибуты печати | |
val attributes = getPrintAttributes() | |
// Получаем PrintAdapter | |
val printAdapter = getPrintAdapter(pdfWebView, jobName) | |
pdfWebView.webChromeClient = object : WebChromeClient() { | |
override fun onProgressChanged(view: WebView, newProgress: Int) { | |
super.onProgressChanged(view, newProgress) | |
// Получаем прогресс загрузки страницы (напрямую, а не через newProgress) | |
val progress = pdfWebView.progress | |
// Когда страница готова, начинаем печать | |
if (progress == 100 && !pdfGenerationStarted) { | |
// Меняем статус | |
pdfGenerationStarted = true | |
// Генерируем PDF с помощью PdfPrinter | |
val pdfPrinter = PdfPrinter(attributes) | |
pdfPrinter.generate(printAdapter, pdfLocation, onPdfGenerated) | |
} | |
} | |
} | |
// Загружаем данные из html | |
pdfWebView.loadDataWithBaseURL(null, htmlString, "text/html", "utf-8", null) | |
} catch (e: Exception) { | |
onPdfGenerationFailed?.invoke(e) | |
} | |
} | |
private fun getPrintAdapter(pdfWebView: WebView, jobName: String): PrintDocumentAdapter { | |
return pdfWebView.createPrintDocumentAdapter(jobName) | |
} | |
// Создаем атрибуты печати, можно настроить под разные размеры | |
private fun getPrintAttributes(pdfPageSize: PrintAttributes.MediaSize = PrintAttributes.MediaSize.ISO_A4): PrintAttributes { | |
return PrintAttributes.Builder().apply { | |
setMediaSize(pdfPageSize) | |
setResolution(Resolution("pdf", Context.PRINT_SERVICE, 600, 600)) | |
setMinMargins(PrintAttributes.Margins.NO_MARGINS) | |
}.build() | |
} | |
} | |
private typealias PdfGeneratedCallback = (File) -> Unit | |
private typealias PdfGenerationFailedCallback = (Exception) -> Unit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment