Супер кринж, но сейчас этот кринж будем делать красивым и чилить
This commit is contained in:
parent
61faa1af74
commit
c1251004ba
@ -1,5 +1,16 @@
|
|||||||
package com.example.myapplication.database.entities.composeui
|
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.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@ -26,19 +37,27 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.example.myapplication.R
|
import com.example.myapplication.R
|
||||||
import com.example.myapplication.api.report.ReportRemote
|
import com.example.myapplication.api.report.ReportRemote
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.OutputStream
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ReportPage (navController: NavController?, viewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory))
|
fun ReportPage (navController: NavController?, viewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory))
|
||||||
{
|
{
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
//viewModel.getReport()
|
||||||
|
|
||||||
val dateStateStart = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)
|
val dateStateStart = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)
|
||||||
val dateStateEnd = 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))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Button(
|
Button(
|
||||||
onClick = {coroutineScope.launch { viewModel.getReport() } },
|
onClick = {coroutineScope.launch {
|
||||||
|
viewModel.getReport()
|
||||||
|
//createPdfFile(context = context, fileName = "отчет.pdf",reportData = reportResultPageState.resReport)
|
||||||
|
} },
|
||||||
enabled = viewModel.reportPageUiState.isEntryValid,
|
enabled = viewModel.reportPageUiState.isEntryValid,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -105,6 +127,22 @@ fun ReportPage (navController: NavController?, viewModel: ReportViewModel = view
|
|||||||
style = MaterialTheme.typography.headlineLarge
|
style = MaterialTheme.typography.headlineLarge
|
||||||
)
|
)
|
||||||
TableScreen(reportData = reportResultPageState.resReport)
|
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(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(16.dp)) {
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
|
||||||
Row(Modifier.background(Color.White)) {
|
Row(Modifier.background(Color.White)) {
|
||||||
TableCell(text = "ID", weight = column1Weight)
|
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.
|
// Here are all the lines of your table.
|
||||||
reportData.forEach {
|
reportData.forEach {
|
||||||
val (productId, productName, sellsAmount, sellsPrice) = it
|
val (id, dateTime, weight, maxCount, bikeId) = it
|
||||||
Row(Modifier.fillMaxWidth()) {
|
Row(Modifier.fillMaxWidth()) {
|
||||||
TableCell(text = productId.toString(), weight = column1Weight)
|
TableCell(text = id.toString(), weight = column1Weight)
|
||||||
TableCell(text = sellsAmount.toString(), weight = column1Weight)
|
TableCell(text = dateTime.toString(), weight = column1Weight)
|
||||||
TableCell(text = sellsPrice.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)
|
||||||
|
}
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user