android打印机字体大小,打印自定义文档  |  Android 开发者  |  Android Developers

本文介绍了如何在Android应用中创建自定义打印输出,涉及连接打印管理器、创建打印适配器及构建打印内容。通过自定义打印适配器,可以精确控制字体大小、文本流、分页符等,适用于需要精美打印效果的场景。示例代码展示了如何使用PrintManager启动打印任务,并实现PrintDocumentAdapter来处理布局和写入打印文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于某些应用,例如绘图应用、页面布局应用以及专注于图形输出的其他应用,创建精美的打印页面是一项重要功能。在这种情况下,打印图片或 HTML 文档是不够的。对于此类应用,打印输出需要精确控制进入页面的所有内容,包括字体、文本流、分页符、页眉、页脚和图形元素。

比起之前讨论的方法,创建完全针对您的应用自定义的打印输出需要投入更多的编程工作。您必须构建与打印框架通信的组件,根据打印机设置做出调整,绘制页面元素以及管理多页打印。

本节课将向您介绍如何连接打印管理器、创建打印适配器和构建打印内容。

连接到打印管理器

当应用直接管理打印过程时,从用户那收到打印请求后的第一步是连接到 Android 打印框架并获取

Kotlin

private fun doPrint() {

activity?.also { context ->

// Get a PrintManager instance

val printManager = context.getSystemService(Context.PRINT_SERVICE) as PrintManager

// Set job name, which will be displayed in the print queue

val jobName = "${context.getString(R.string.app_name)} Document"

// Start a print job, passing in a PrintDocumentAdapter implementation

// to handle the generation of a print document

printManager.print(jobName, MyPrintDocumentAdapter(context), null)

}

}Java

private void doPrint() {

// Get a PrintManager instance

PrintManager printManager = (PrintManager) getActivity()

.getSystemService(Context.PRINT_SERVICE);

// Set job name, which will be displayed in the print queue

String jobName = getActivity().getString(R.string.app_name) + " Document";

// Start a print job, passing in a PrintDocumentAdapter implementation

// to handle the generation of a print document

printManager.print(jobName, new MyPrintDocumentAdapter(getActivity()),

null); //

}

以上示例代码演示了如何命名打印作业和设置处理打印生命周期步骤的

注意:

创建打印适配器

打印适配器与 Android 打印框架互动,并处理打印过程的步骤。此过程要求用户在创建打印文档前先选择打印机和打印选项。当用户选择具有不同输出功能、不同页面大小或不同页面方向的打印机时,这些选择会影响最终输出。在进行这些选择时,打印框架会要求您的适配器设置布局并生成打印文档,为最终输出做准备。当用户点按打印按钮后,框架将接受最终打印文档并将其传递给打印提供器以进行输出。在打印过程中,用户可以选择取消打印操作,因此打印适配器还必须监听和回应取消请求。

以下几部分介绍了如何实现布局和写入方法,这些方法对于打印适配器的正常运行至关重要。

注意:这些适配器方法是在应用的主线程上调用的。如果您预计在实现中执行这些方法要花费大量时间,则将它们实现为在单独的线程内执行。例如,您可以将布局或打印文档写入工作封装在单独的

计算打印文档信息

Kotlin

override fun onLayout(

oldAttributes: PrintAttributes?,

newAttributes: PrintAttributes,

cancellationSignal: CancellationSignal?,

callback: LayoutResultCallback,

extras: Bundle?

) {

// Create a new PdfDocument with the requested page attributes

pdfDocument = PrintedPdfDocument(activity, newAttributes)

// Respond to cancellation request

if (cancellationSignal?.isCanceled == true) {

callback.onLayoutCancelled()

return

}

// Compute the expected number of printed pages

val pages = computePageCount(newAttributes)

if (pages > 0) {

// Return print information to print framework

PrintDocumentInfo.Builder("print_output.pdf")

.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)

.setPageCount(pages)

.build()

.also { info ->

// Content layout reflow is complete

callback.onLayoutFinished(info, true)

}

} else {

// Otherwise report an error to the print framework

callback.onLayoutFailed("Page count calculation failed.")

}

}Java

@Override

public void onLayout(PrintAttributes oldAttributes,

PrintAttributes newAttributes,

CancellationSignal cancellationSignal,

LayoutResultCallback callback,

Bundle metadata) {

// Create a new PdfDocument with the requested page attributes

pdfDocument = new PrintedPdfDocument(getActivity(), newAttributes);

// Respond to cancellation request

if (cancellationSignal.isCanceled() ) {

callback.onLayoutCancelled();

return;

}

// Compute the expected number of printed pages

int pages = computePageCount(newAttributes);

if (pages > 0) {

// Return print information to print framework

PrintDocumentInfo info = new PrintDocumentInfo

.Builder("print_output.pdf")

.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)

.setPageCount(pages)

.build();

// Content layout reflow is complete

callback.onLayoutFinished(info, true);

} else {

// Otherwise report an error to the print framework

callback.onLayoutFailed("Page count calculation failed.");

}

}

执行

注意:

Kotlin

private fun computePageCount(printAttributes: PrintAttributes): Int {

var itemsPerPage = 4 // default item count for portrait mode

val pageSize = printAttributes.mediaSize

if (!pageSize.isPortrait) {

// Six items per page in landscape orientation

itemsPerPage = 6

}

// Determine number of print items

val printItemCount: Int = getPrintItemCount()

return Math.ceil((printItemCount / itemsPerPage.toDouble())).toInt()

}Java

private int computePageCount(PrintAttributes printAttributes) {

int itemsPerPage = 4; // default item count for portrait mode

MediaSize pageSize = printAttributes.getMediaSize();

if (!pageSize.isPortrait()) {

// Six items per page in landscape orientation

itemsPerPage = 6;

}

// Determine number of print items

int printItemCount = getPrintItemCount();

return (int) Math.ceil(printItemCount / itemsPerPage);

}

写入打印文档文件

到了要将打印输出写入文件时,Android 打印框架会调用应用的

注意:每次调用 false,以免不必要地重写打印文档。

注意:

以下示例演示了该过程的基本机制,并使用

Kotlin

override fun onWrite(

pageRanges: Array,

destination: ParcelFileDescriptor,

cancellationSignal: CancellationSignal?,

callback: WriteResultCallback

) {

// Iterate over each page of the document,

// check if it's in the output range.

for (i in 0 until totalPages) {

// Check to see if this page is in the output range.

if (containsPage(pageRanges, i)) {

// If so, add it to writtenPagesArray. writtenPagesArray.size()

// is used to compute the next output page index.

writtenPagesArray.append(writtenPagesArray.size(), i)

pdfDocument?.startPage(i)?.also { page ->

// check for cancellation

if (cancellationSignal?.isCanceled == true) {

callback.onWriteCancelled()

pdfDocument?.close()

pdfDocument = null

return

}

// Draw page content for printing

drawPage(page)

// Rendering is complete, so page can be finalized.

pdfDocument?.finishPage(page)

}

}

}

// Write PDF document to file

try {

pdfDocument?.writeTo(FileOutputStream(destination.fileDescriptor))

} catch (e: IOException) {

callback.onWriteFailed(e.toString())

return

} finally {

pdfDocument?.close()

pdfDocument = null

}

val writtenPages = computeWrittenPages()

// Signal the print framework the document is complete

callback.onWriteFinished(writtenPages)

...

}Java

@Override

public void onWrite(final PageRange[] pageRanges,

final ParcelFileDescriptor destination,

final CancellationSignal cancellationSignal,

final WriteResultCallback callback) {

// Iterate over each page of the document,

// check if it's in the output range.

for (int i = 0; i < totalPages; i++) {

// Check to see if this page is in the output range.

if (containsPage(pageRanges, i)) {

// If so, add it to writtenPagesArray. writtenPagesArray.size()

// is used to compute the next output page index.

writtenPagesArray.append(writtenPagesArray.size(), i);

PdfDocument.Page page = pdfDocument.startPage(i);

// check for cancellation

if (cancellationSignal.isCanceled()) {

callback.onWriteCancelled();

pdfDocument.close();

pdfDocument = null;

return;

}

// Draw page content for printing

drawPage(page);

// Rendering is complete, so page can be finalized.

pdfDocument.finishPage(page);

}

}

// Write PDF document to file

try {

pdfDocument.writeTo(new FileOutputStream(

destination.getFileDescriptor()));

} catch (IOException e) {

callback.onWriteFailed(e.toString());

return;

} finally {

pdfDocument.close();

pdfDocument = null;

}

PageRange[] writtenPages = computeWrittenPages();

// Signal the print framework the document is complete

callback.onWriteFinished(writtenPages);

...

}

此示例将 PDF 页面内容的呈现委托给 drawPage() 方法,详见下一部分的讨论。

和布局一样,执行

注意:呈现文档进行打印可能是一项消耗大量资源的操作。为了避免阻塞应用的主界面线程,应考虑在单独的线程上执行页面呈现和写入操作,例如在 进程和线程。

绘制 PDF 页面内容

当应用进行打印时,应用必须生成 PDF 文档并将其传递到 Android 打印框架进行打印。您可以将任何 PDF 生成库用于此目的。本节课介绍如何使用

Kotlin

private fun drawPage(page: PdfDocument.Page) {

page.canvas.apply {

// units are in points (1/72 of an inch)

val titleBaseLine = 72f

val leftMargin = 54f

val paint = Paint()

paint.color = Color.BLACK

paint.textSize = 36f

drawText("Test Title", leftMargin, titleBaseLine, paint)

paint.textSize = 11f

drawText("Test paragraph", leftMargin, titleBaseLine + 25, paint)

paint.color = Color.BLUE

drawRect(100f, 100f, 172f, 172f, paint)

}

}Java

private void drawPage(PdfDocument.Page page) {

Canvas canvas = page.getCanvas();

// units are in points (1/72 of an inch)

int titleBaseLine = 72;

int leftMargin = 54;

Paint paint = new Paint();

paint.setColor(Color.BLACK);

paint.setTextSize(36);

canvas.drawText("Test Title", leftMargin, titleBaseLine, paint);

paint.setTextSize(11);

canvas.drawText("Test paragraph", leftMargin, titleBaseLine + 25, paint);

paint.setColor(Color.BLUE);

canvas.drawRect(100, 100, 172, 172, paint);

}

使用

提示:虽然

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值