From c1251004ba5c8d90e783ab7afc8b03bb4f332171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B8=D0=BD=20=D0=9C=D0=B0=D0=BA=D1=81?= =?UTF-8?q?=D0=B8=D0=BC?= Date: Mon, 25 Dec 2023 22:22:48 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A1=D1=83=D0=BF=D0=B5=D1=80=20=D0=BA=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=B6,=20=D0=BD=D0=BE=20=D1=81=D0=B5=D0=B9=D1=87?= =?UTF-8?q?=D0=B0=D1=81=20=D1=8D=D1=82=D0=BE=D1=82=20=D0=BA=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B6=20=D0=B1=D1=83=D0=B4=D0=B5=D0=BC=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D1=82=D1=8C=20=D0=BA=D1=80=D0=B0=D1=81=D0=B8=D0=B2?= =?UTF-8?q?=D1=8B=D0=BC=20=D0=B8=20=D1=87=D0=B8=D0=BB=D0=B8=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../database/entities/composeui/ReportPage.kt | 128 ++++++++++++++++-- .../entities/composeui/UserProfile.kt | 50 ------- 2 files changed, 115 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/example/myapplication/database/entities/composeui/ReportPage.kt b/app/src/main/java/com/example/myapplication/database/entities/composeui/ReportPage.kt index 776f85b..dc2bbc4 100644 --- a/app/src/main/java/com/example/myapplication/database/entities/composeui/ReportPage.kt +++ b/app/src/main/java/com/example/myapplication/database/entities/composeui/ReportPage.kt @@ -1,5 +1,16 @@ package com.example.myapplication.database.entities.composeui +import android.content.ContentResolver +import android.content.ContentValues +import android.content.Context +import android.content.Intent +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.pdf.PdfDocument +import android.net.Uri +import android.os.Environment +import android.provider.MediaStore +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement @@ -26,19 +37,27 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.example.myapplication.R import com.example.myapplication.api.report.ReportRemote +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.IOException +import java.io.OutputStream import java.util.Date @OptIn(ExperimentalMaterial3Api::class) @Composable fun ReportPage (navController: NavController?, viewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory)) { + val context = LocalContext.current + + //viewModel.getReport() val dateStateStart = rememberDatePickerState(initialDisplayMode = DisplayMode.Input) val dateStateEnd = rememberDatePickerState(initialDisplayMode = DisplayMode.Input) @@ -88,7 +107,10 @@ fun ReportPage (navController: NavController?, viewModel: ReportViewModel = view Spacer(modifier = Modifier.height(16.dp)) Button( - onClick = {coroutineScope.launch { viewModel.getReport() } }, + onClick = {coroutineScope.launch { + viewModel.getReport() + //createPdfFile(context = context, fileName = "отчет.pdf",reportData = reportResultPageState.resReport) + } }, enabled = viewModel.reportPageUiState.isEntryValid, modifier = Modifier .fillMaxWidth() @@ -105,6 +127,22 @@ fun ReportPage (navController: NavController?, viewModel: ReportViewModel = view style = MaterialTheme.typography.headlineLarge ) TableScreen(reportData = reportResultPageState.resReport) + Spacer(modifier = Modifier.height(16.dp)) + Button( + onClick = {coroutineScope.launch { + //viewModel.getReport() + createPdfFile(context = context, fileName = "отчет.pdf",reportData = reportResultPageState.resReport) + } }, + enabled = viewModel.reportPageUiState.isEntryValid, + modifier = Modifier + .fillMaxWidth() + .padding(all = 10.dp) + .border(4.dp, MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(10.dp)), + shape = RoundedCornerShape(10.dp), + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary) + ) { + Text("Сформировать отчет PDF") + } } } @@ -131,26 +169,90 @@ fun TableScreen(reportData: List) { Column( Modifier - .padding(16.dp)) { + .padding(16.dp) + ) { Row(Modifier.background(Color.White)) { TableCell(text = "ID", weight = column1Weight) - TableCell(text = "Товар", weight = column1Weight) - TableCell(text = "Кол-во", weight = column1Weight) - TableCell(text = "Цена", weight = column1Weight) + TableCell(text = "Дата и время", weight = column1Weight) + TableCell(text = "Вес", weight = column1Weight) + TableCell(text = "Макс. количество", weight = column1Weight) + TableCell(text = "ID велосипеда", weight = column1Weight) } // Here are all the lines of your table. reportData.forEach { - val (productId, productName, sellsAmount, sellsPrice) = it + val (id, dateTime, weight, maxCount, bikeId) = it Row(Modifier.fillMaxWidth()) { - TableCell(text = productId.toString(), weight = column1Weight) - TableCell(text = sellsAmount.toString(), weight = column1Weight) - TableCell(text = sellsPrice.toString(), weight = column1Weight) + TableCell(text = id.toString(), weight = column1Weight) + TableCell(text = dateTime.toString(), weight = column1Weight) + TableCell(text = weight.toString(), weight = column1Weight) + TableCell(text = maxCount.toString(), weight = column1Weight) + TableCell(text = bikeId.toString(), weight = column1Weight) } } -/* Row(Modifier.fillMaxWidth()) { - TableCell(text = "Общая цена: " + reportData.map { x -> x.sellsPrice}.sum().toString(), weight = column2Weight) - }*/ } -} \ No newline at end of file +} + +suspend fun createPdfFile(context: Context, fileName: String, reportData: List) { + withContext(Dispatchers.IO) { + val contentValues = ContentValues().apply { + put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) + put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf") + put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS) + } + + val contentResolver: ContentResolver = context.contentResolver + val uri: Uri? = contentResolver.insert(MediaStore.Files.getContentUri("external"), contentValues) + + uri?.let { + try { + contentResolver.openOutputStream(uri)?.use { outputStream -> + createPdfContent(outputStream, reportData) + } + + // Optional: Notify MediaStore about the new file + context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)) + } catch (e: IOException) { + e.printStackTrace() + } + } + } +} + +private fun createPdfContent(outputStream: OutputStream, reportData: List) { + val pdfDocument = PdfDocument() + + val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create() + val page = pdfDocument.startPage(pageInfo) + val canvas = page.canvas + + val paint = Paint() + paint.color = android.graphics.Color.BLACK + paint.textSize = 24f + + // Отображаем заголовок + val title = "Отчет" + val xTitle = (pageInfo.pageWidth - paint.measureText(title)) / 2 + val yTitle = 40f + canvas.drawText(title, xTitle, yTitle, paint) + + // Отображаем данные из запроса + val yStart = yTitle + 40f + val lineHeight = 40f + for ((index, report) in reportData.withIndex()) { + val y = yStart + index * lineHeight + Log.d("Проверка данных","${report.id} | ${report.dateTime} | ${report.weight} | ${report.maxCount} | ${report.bikeId}") + val text = "${report.id} | ${report.dateTime} | ${report.weight} | ${report.maxCount} | ${report.bikeId}" + canvas.drawText(text, 40f, y, paint) + } + + pdfDocument.finishPage(page) + + pdfDocument.writeTo(outputStream) + pdfDocument.close() +} + +private fun drawCell(canvas: Canvas, paint: Paint, text: String, x: Float, y: Float, width: Int) { + canvas.drawText(text, x + (width - paint.measureText(text)) / 2, y + paint.textSize, paint) +} diff --git a/app/src/main/java/com/example/myapplication/database/entities/composeui/UserProfile.kt b/app/src/main/java/com/example/myapplication/database/entities/composeui/UserProfile.kt index 2eca0c2..4fad51f 100644 --- a/app/src/main/java/com/example/myapplication/database/entities/composeui/UserProfile.kt +++ b/app/src/main/java/com/example/myapplication/database/entities/composeui/UserProfile.kt @@ -425,53 +425,3 @@ fun LoginScreenProfile(currentUserViewModel: CurrentUserViewModel = viewModel(fa } } -@OptIn(ExperimentalComposeUiApi::class) -suspend fun createPdfFile(context: Context, fileName: String) { - withContext(Dispatchers.IO) { - val contentValues = ContentValues().apply { - put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) - put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf") - put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS) - } - - val contentResolver: ContentResolver = context.contentResolver - val uri: Uri? = contentResolver.insert(MediaStore.Files.getContentUri("external"), contentValues) - - uri?.let { - try { - contentResolver.openOutputStream(uri)?.use { outputStream -> - createPdfContent(outputStream) - } - - // Optional: Notify MediaStore about the new file - context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)) - } catch (e: IOException) { - e.printStackTrace() - } - } - } -} - -private fun createPdfContent(outputStream: OutputStream) { - val pdfDocument = PdfDocument() - - val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create() - val page = pdfDocument.startPage(pageInfo) - val canvas = page.canvas - - val paint = Paint() - paint.color = Color.BLACK - paint.textSize = 24f - - val text = "Привет, мир!" - val x = (pageInfo.pageWidth - paint.measureText(text)) / 2 - val y = (pageInfo.pageHeight + paint.textSize) / 2 - - canvas.drawText(text, x, y, paint) - - pdfDocument.finishPage(page) - - pdfDocument.writeTo(outputStream) - pdfDocument.close() -} -