Skip to content

Instantly share code, notes, and snippets.

@stakancheck
Created April 17, 2024 11:49
Show Gist options
  • Save stakancheck/2f26fc4897dacc765261241c1fd39848 to your computer and use it in GitHub Desktop.
Save stakancheck/2f26fc4897dacc765261241c1fd39848 to your computer and use it in GitHub Desktop.
PDFGenerator example
class PdfGenerator(private val context: Context) {
private val htmlToPdfConvertor = HtmlToPdfConvertor(context)
// Функция генерации и сохранения
suspend fun generateExpertAct(
act: ActSave,
images: List<File>,
outFile: File
): Result<Unit> {
return suspendCoroutine { continuation ->
Handler(Looper.getMainLooper()).post {
htmlToPdfConvertor.convert(
pdfLocation = outFile,
htmlString = generateExpertActHtml(
act = act,
images = images
),
onPdfGenerationFailed = { exception ->
continuation.resume(Result.failure(exception))
},
onPdfGenerated = {
continuation.resume(Result.success(Unit))
}
)
}
}
}
private fun generateExpertActHtml(
act: ActSave,
images: List<File>
): String {
// Генерируем шапку файла
val documentInfoHeader: String = generateDocumentInfoHeader(
act.object_,
act.address,
act.owner
)
// Список картинок для таблицы
var imagesToAdd = mutableListOf<String>()
// Основной контент, таблица с комментариями
val tableObservationsContent = buildString {
for (room in act.rooms) {
for (item in room.items) {
append(generateItemTableLine(room.room_name, item.item_name))
for (observation in item.observes) {
append(
generateItemTableObservation(
observation.problem_description,
observation.standard_description,
observation.comment,
generateImagesData(
imagesToAdd.size,
observation.images
)
)
)
// Добавляем картинки из записи, для таблицы картинок
imagesToAdd.addAll(observation.images)
}
}
}
}
// Таблица картинок
val tableImagesContent = buildString {
for (i in 0 until imagesToAdd.size step 2) {
val image1 = images.findLast { it.name == imagesToAdd[i] }?.absolutePath
val image2 =
images.findLast { it.name == imagesToAdd.getOrNull(i + 1) }?.absolutePath
if (image1 != null) {
append(
generateImageTableLine(
i + 1, // Номер картинки
image1, // Картинка слева
image2 // Картинка справа
)
)
}
}
}
// Возвращаем готовый HTML контент
return buildString {
append(PREFIX)
append(STYLE)
append(
surroundWithBody(
buildString {
append(documentInfoHeader)
append(
surroundWithTableObservations(
tableObservationsContent
)
)
append(
surroundWithTableImages(
tableImagesContent
)
)
}
)
)
append(SUFFIX)
}
}
<..>
companion object {
const val TAG: String = "PdfGenerator"
private val PREFIX = """
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Report</title>
</head>
""".trimIndent()
private val SUFFIX = """
</html>
""".trimIndent()
private val STYLE = """
<style>
table, td {
border: 1px solid;
padding: 5px;
}
td {
font-family: "Times New Roman", serif;
font-style: normal;
font-weight: normal;
text-decoration: none;
font-size: 12pt;
vertical-align: top;
text-align: left;
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
h1 {
font-family: "Times New Roman", serif;
font-style: normal;
font-weight: bold;
text-decoration: none;
font-size: 18pt;
}
h3 {
font-family: "Times New Roman", serif;
font-style: normal;
font-weight: bold;
text-decoration: none;
font-size: 14pt;
}
.break-before {
page-break-before: always;
}
th {
text-align: left;
}
* {
overflow: visible !important;
}
table {
page-break-before: avoid !important;
}
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
page-break-before: auto;
}
img {
max-width: 100%;
max-height: 100%;
}
@page {
size: A4;
margin: 10mm;
}
@media print {
body {
width: 210mm;
height: 297mm;
}
}
</style>
""".trimIndent()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment