我想通过Wifi/Bleutooth打印机打印PDF文件,但在此之前,我想连接到打印机
我已经尝试了一种方法来做到这一点,但问题是我的打印机尺寸小于pdf页面大小(A4)
如何使文件与所有大小的打印机兼容?
下面是一些代码:
private fun savePdf(
invoiceType: String,
invoiceModel: SalesDatabase,
date: String,
personType: String,
personName: String,
paymentMethod: String
) {
val am: AssetManager = context.assets
var font: PdfFont?
try {
am.open("text.ttf").use { inStream ->
val buffer = ByteArrayOutputStream()
var nRead: Int
val data = ByteArray(16384)
while (inStream.read(data, 0, data.size).also { nRead = it } != -1) {
buffer.write(data, 0, nRead)
}
font = PdfFontFactory.createFont(buffer.toByteArray(), PdfEncodings.UTF8)
}
} catch (e: Exception) {
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
return
}
val mFileName = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(System.currentTimeMillis())
val mFilePath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
.toString() + "/" + "$invoiceType Invoice" + mFileName + ".pdf"
val file = File(mFilePath)
file.createNewFile()
val outputStream: OutputStream = FileOutputStream(file)
val pdfWriter = PdfWriter(outputStream)
val pdfDocument = PdfDocument(pdfWriter)
val mDoc = Document(pdfDocument)
try {
if (file.exists()) {
//Setting
mDoc.pdfDocument.defaultPageSize = PageSize.A4
val typeInvoice = "Invoice $invoiceType"
val text =
Paragraph(typeInvoice).setBold().setFontColor(ColorConstants.BLACK)
.setFont(font).setTextAlignment(TextAlignment.CENTER).setFontSize(22f)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
val textWidth = PageSize.A4.width
val table1 = Table(FloatArray(1) { textWidth })
table1.addCell(
Cell().add(text)
.setBorder(Border.NO_BORDER)
.setHorizontalAlignment(HorizontalAlignment.CENTER)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
)
mDoc.add(table1)
addLineSpace(mDoc)
val width = PageSize.A4.width / 3
val columns = FloatArray(3)
columns[0] = width
columns[1] = width
columns[2] = width
val infoTable = Table(columns)
val theDate =
Paragraph("Date : $date").setBold().setFont(font)
.setFontColor(ColorConstants.BLACK)
.setTextAlignment(TextAlignment.CENTER).setFontSize(12f)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
val theTypeName =
Paragraph("$personType Name: $personName").setBold().setFont(font)
.setFontColor(ColorConstants.BLACK)
.setTextAlignment(TextAlignment.CENTER).setFontSize(12f)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
val thePaymentType =
Paragraph("Payment method : $paymentMethod").setBold().setFont(font)
.setFontColor(ColorConstants.BLACK)
.setTextAlignment(TextAlignment.CENTER).setFontSize(12f)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
infoTable.addCell(
Cell().add(theDate)
.setBorder(Border.NO_BORDER)
.setHorizontalAlignment(HorizontalAlignment.CENTER)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
)
infoTable.addCell(
Cell().add(theTypeName)
.setBorder(Border.NO_BORDER)
.setHorizontalAlignment(HorizontalAlignment.CENTER)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
)
infoTable.addCell(
Cell().add(thePaymentType)
.setBorder(Border.NO_BORDER)
.setHorizontalAlignment(HorizontalAlignment.CENTER)
.setTextAlignment(TextAlignment.CENTER)
.setVerticalAlignment(VerticalAlignment.MIDDLE)
)
mDoc.add(infoTable)
addLineSpace(mDoc)
addLineSeparator(mDoc)
addLineSpace(mDoc)
addTable(mDoc, invoiceModel, font)
}
mDoc.close()
showPleaseWaitDialog(false, "")
Toast.makeText(context, "تم إنشاء الملف", Toast.LENGTH_LONG).show()
Toast.makeText(context, "تم حفظ الملف في $mFilePath", Toast.LENGTH_LONG).show()
Handler().postDelayed({
// val intent = Intent(context, ShowPdf::class.java)
// intent.putExtra("pdfUrl", mFilePath)
// context.startActivity(intent)
printPDF(file)
}, 1000)
} catch (e: Exception) {
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
}
}
private fun printPDF(file: File) {
if (OptionDatabase.isWifiMode(context)) {
val printManager: PrintManager? =
getSystemService(context, PrintManager::class.java)
try {
val printDocumentAdapter: PrintDocumentAdapter =
PdfDocumentAdapter(context, file.path)
printManager!!.print(
"Document",
printDocumentAdapter,
PrintAttributes.Builder().build()
)
} catch (ex: java.lang.Exception) {
Toast.makeText(context, "Can't read pdf file", Toast.LENGTH_SHORT).show()
}
return
}
if (OptionDatabase.isBluetoothMode(context)) {
Printooth.printer().printingCallback = this
Printooth.printer().print(pdfToBitmap(file))
return
}
}
private fun pdfToBitmap(pdfFile: File): ArrayList<Printable> {
val bitmaps = ArrayList<Printable>()
try {
val renderer = PdfRenderer(
ParcelFileDescriptor.open(
pdfFile,
ParcelFileDescriptor.MODE_READ_ONLY
)
)
var bitmap: Bitmap
val pageCount = renderer.pageCount
for (i in 0 until pageCount) {
val page = renderer.openPage(i)
val width: Int =
resources.displayMetrics.densityDpi / 72 * page.width
val height: Int =
resources.displayMetrics.densityDpi / 72 * page.height
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
bitmaps.add(ImagePrintable.Builder(bitmap).build())
// close the page
page.close()
}
// close the renderer
renderer.close()
} catch (ex: java.lang.Exception) {
context.showToast(ex.message.toString(), 0)
}
return bitmaps
}
private fun addTable(document: Document, invoiceModel: PurchaseDatabase, font: PdfFont?) {
val columns = FloatArray(5)
columns[0] = 30f
columns[1] = (PageSize.A4.width - 30f) / 4
columns[2] = (PageSize.A4.width - 30f) / 4
columns[3] = (PageSize.A4.width - 30f) / 4
columns[4] = (PageSize.A4.width - 30f) / 4
val table = Table(columns).setMarginBottom(20f)
addCell(table, "", font!!, true)
addCell(table, "Product Name", font, true)
addCell(table, "Price", font, true)
addCell(table, "Quantity", font, true)
addCell(table, "Total", font, true)
val myType = object : TypeToken<ArrayList<ProductBuyModel>>() {}.type
val products =
Gson().fromJson<ArrayList<ProductBuyModel>>(invoiceModel.products, myType)
for (s in products.indices) {
addCell(table, (s + 1).toString(), font, false)
addCell(table, products[s].productName, font, false)
val price =
(products[s].productPrixTotal - products[s].productTax) / products[s].productQuantity
addCell(table, price.toString(), font, false)
addCell(table, products[s].productQuantity.toString(), font, false)
addCell(table, products[s].productPrixTotal.toString(), font, false)
}
addCell(table, "", font, false)
addCell(table, "", font, false)
addCell(table, "Payment : ${invoiceModel.paymentPrice}", font, true)
addCell(table, "Rest : ${invoiceModel.restPrice}", font, true)
addCell(table, "Total : ${invoiceModel.totalPrice}", font, true)
table.setBackgroundColor(ColorConstants.WHITE)
table.isKeepTogether = true
document.add(table)
}
当我尝试我的代码时,结果如下:
1条答案
按热度按时间mzillmmw1#
您使用的是哪种类型的打印机?与使用Windows打印驱动程序打印相比,使用这些连接到Android的小型移动的打印机打印可能会有点棘手。
根据型号的不同,这台打印机将有一个本地语言(Zebra有Zebra打印语言又名ZPL,是最流行的语言之一)。通常你不会打印原始PDF,而是发送嵌入在ZPL /本地打印机语言中的打印数据。虽然这听起来很复杂,但它确实使一些事情变得容易(特别是当需要条形码时)。Zebra打印语言信息供参考
大小普遍可能有点坚韧,因为大多数打印机的索引点(绝对)和利用不同的字体/大小。我想这可以做到,但我还没有看到它。
在这两种情况下,连接都非常简单。您可以简单地ping IP打印机,然后打开一个套接字并发送打印流。对于蓝牙,您可以打开一个蓝牙套接字,然后关闭它,从而找出它是否存在和在线。下面的代码假设您有一个打印机列表和它们的地址(IP或蓝牙)。注意:下面的代码应该封装在一个AsyncTask doinbackground方法中,并且假设你的原始打印数据在params 1元素中。另外,下面的代码是Java的,但是Kotlin转换应该非常简单!
在蓝牙世界中连接有点复杂,但仍然相当简单。只需设置一个意图/广播接收器匹配,这样你就可以开始发现过程并选择一个BT设备。这也给了你选择配对设备或实际与一个新设备配对的选项!类似于下面的内容:
下面是一些小问题:移动终端/应用程序/打印机组合可能会导致一些时间问题,这是我们多年来看到的。您可能需要在发送时引入一个小的字符延迟,但这取决于移动设备/应用程序/打印机组合。如果您在尝试打印时没有响应,请尝试添加一个小的字符延迟(5 ms/10 ms)
上面的代码当然不是唯一的方法来做到这一点,我相信有一些优化,我们可以添加,但这已经工作了多年的多个移动终端制造商和移动打印机制造商!
有更多的东西可以解释在一个职位,但这应该希望至少给予你一个方向!