Супер кринж, но сейчас этот кринж будем делать красивым и чилить

This commit is contained in:
Кашин Максим 2023-12-25 22:22:48 +04:00
parent 61faa1af74
commit c1251004ba
2 changed files with 115 additions and 63 deletions

View File

@ -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<ReportRemote>) {
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)
}*/
}
}
}
suspend fun createPdfFile(context: Context, fileName: String, reportData: List<ReportRemote>) {
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<ReportRemote>) {
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)
}

View File

@ -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()
}