Skip to main content

Print Functionality Implementation

Overview

In Weda application development, printing functionality is a core requirement for many business scenarios (such as order management, warehouse logistics, retail checkout, etc.). This article will detail how to implement printer invocation in Weda applications, including web printing, cloud printing service integration, and mini program printing solutions.

Applicable Scenarios

  • Order Printing: E-commerce orders, food delivery orders, delivery slips
  • Receipt Printing: Receipts, invoices, vouchers
  • Label Printing: Product labels, barcode labels, logistics labels
  • Report Printing: Business reports, statistical reports, approval documents

Implementation Solutions

Solution 1: Web Printing (Web Applications)

Suitable for Weda web applications, implementing print functionality through the browser's native print API.

1. Basic Print Implementation

Create a custom method printContent:

export default async function ({ event, data }) {
// Trigger browser print dialog
window.print();
}

Call this method in a button's click event to trigger printing.

2. Print Specific Area Content

If you only want to print a specific area of the page, use the following method:

export default async function ({ event, data }) {
// 1. Get the content element to print
const printArea = document.getElementById('print-area');

if (!printArea) {
$w.utils.showToast({
title: "Print area not found",
icon: "error",
duration: 2000,
});
return;
}

// 2. Save original page content
const originalContent = document.body.innerHTML;

// 3. Replace page content with print area content
document.body.innerHTML = printArea.innerHTML;

// 4. Trigger print
window.print();

// 5. Restore original page content
document.body.innerHTML = originalContent;

// 6. Reload page (optional, to restore page interaction)
window.location.reload();
}

3. Optimize with Print Styles

Add print-specific styles in the application's custom CSS:

/* Hide unnecessary elements when printing */
@media print {
/* Hide navbar, buttons, and other non-print elements */
.no-print,
.navbar,
.sidebar,
button {
display: none !important;
}

/* Print area style optimization */
.print-area {
width: 100%;
padding: 20px;
font-size: 14px;
}

/* Force page break */
.page-break {
page-break-after: always;
}

/* Avoid element truncation */
.no-break {
page-break-inside: avoid;
}
}

Add the print-area class name to the container component that needs to be printed:

Steps in Weda:

  1. Select the container component to be printed (such as container, form container, etc.)
  2. In the right properties panel, click "Component Configuration" → "Style"
  3. Find the "className" configuration item and enter print-area
  4. Also set the component ID to print-area (set in "Basic" configuration)

Add Class Name Example

4. Advanced Print Features

Use the third-party library print-js for more powerful print features:

Step 1: Include print-js library

Add external dependencies in application settings:

https://printjs-4de6.kxcdn.com/print.min.js
https://printjs-4de6.kxcdn.com/print.min.css

Step 2: Implement print method

export default async function ({ event, data }) {
try {
// Print HTML element
printJS({
printable: 'print-area', // Element ID
type: 'html',
targetStyles: ['*'], // Keep all styles
style: `
.print-area {
font-family: Arial, sans-serif;
font-size: 14px;
line-height: 1.6;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
`,
});
} catch (error) {
console.error('Print failed:', error);
$w.utils.showToast({
title: "Print failed, please try again",
icon: "error",
duration: 2000,
});
}
}

Print PDF files:

export default async function ({ event, data }) {
// Assume data.pdfUrl is the PDF file link
const pdfUrl = data.pdfUrl || 'https://example.com/document.pdf';

printJS({
printable: pdfUrl,
type: 'pdf',
showModal: true, // Show loading popup
});
}

Print images:

export default async function ({ event, data }) {
const imageUrl = data.imageUrl || 'https://example.com/image.jpg';

printJS({
printable: imageUrl,
type: 'image',
header: 'Product Label', // Optional title
});
}

Print JSON data table:

export default async function ({ event, data }) {
const tableData = [
{ name: 'Product A', quantity: 10, price: 100 },
{ name: 'Product B', quantity: 5, price: 200 },
{ name: 'Product C', quantity: 8, price: 150 },
];

printJS({
printable: tableData,
type: 'json',
properties: ['name', 'quantity', 'price'], // Fields to display
header: '<h3>Product List</h3>', // Table title
gridHeaderStyle: 'color: #000; border: 1px solid #ddd; padding: 8px;',
gridStyle: 'border: 1px solid #ddd; padding: 8px;',
});
}

Implement remote printing and batch printing by integrating cloud printing services (such as Feie Cloud Print, Yilianyun, etc.).

Using Feie Cloud Print as Example

Step 1: Register Feie Cloud Print Account

Visit Feie Cloud Print Official Website to register an account and add printer devices.

Step 2: Create Cloud Function

Create a cloud function printOrder in the CloudBase console:

const cloud = require('@cloudbase/node-sdk');
const crypto = require('crypto');
const axios = require('axios');

// Feie Cloud Print configuration
const FEI_E_CONFIG = {
user: 'your_feie_user', // Feie Cloud username
ukey: 'your_feie_ukey', // Feie Cloud UKEY
sn: 'your_printer_sn', // Printer serial number
};

// Generate Feie Cloud signature
function generateSign(params) {
const keys = Object.keys(params).sort();
const str = keys.map(key => `${key}=${params[key]}`).join('&') + FEI_E_CONFIG.ukey;
return crypto.createHash('sha1').update(str).digest('hex');
}

exports.main = async (event, context) => {
const { content, times = 1 } = event;

try {
// Build print content (Feie Cloud format)
const printContent = `
<CB>Order Details</CB><BR>
<C>--------------------------------</C><BR>
Order No.: ${content.orderNo}<BR>
Order Time: ${content.orderTime}<BR>
<C>--------------------------------</C><BR>
<B>Product List</B><BR>
${content.items.map(item =>
`${item.name} x${item.quantity} $${item.price}<BR>`
).join('')}
<C>--------------------------------</C><BR>
<RIGHT>Total: <BOLD>$${content.totalAmount}</BOLD></RIGHT><BR>
<C>================================</C><BR>
<C>Thank you for your purchase!</C><BR>
<QR>https://example.com/order/${content.orderNo}</QR>
`.trim();

// Call Feie Cloud print API
const params = {
user: FEI_E_CONFIG.user,
stime: Math.floor(Date.now() / 1000),
sig: '',
apiname: 'Open_printMsg',
sn: FEI_E_CONFIG.sn,
content: printContent,
times: times,
};

params.sig = generateSign(params);

const response = await axios.post(
'http://api.feieyun.cn/Api/Open/',
new URLSearchParams(params)
);

console.log('Print result:', response.data);

return {
success: true,
data: response.data,
};
} catch (error) {
console.error('Print failed:', error);
return {
success: false,
error: error.message,
};
}
};

Step 3: Call in Weda Application

Create a click event method for the print button:

export default async function ({ event, data }) {
try {
// 1. Get order data
const orderData = {
orderNo: 'ORD202603200001',
orderTime: new Date().toLocaleString(),
items: [
{ name: 'Product A', quantity: 2, price: 50 },
{ name: 'Product B', quantity: 1, price: 100 },
],
totalAmount: 200,
};

// 2. Call cloud function to print
const result = await $w.cloud.callFunction({
name: 'printOrder',
data: {
content: orderData,
times: 1, // Number of copies
},
});

if (result.success) {
$w.utils.showToast({
title: "Print successful",
icon: "success",
duration: 2000,
});
} else {
throw new Error(result.error);
}
} catch (error) {
console.error('Print failed:', error);
$w.utils.showToast({
title: "Print failed: " + error.message,
icon: "error",
duration: 3000,
});
}
}

Feie Cloud Print Tag Description

TagDescriptionExample
<BR>Line breakProduct Name<BR>
<CB>Text</CB>Center bold<CB>Title</CB>
<C>Text</C>Center<C>Content</C>
<B>Text</B>Bold<B>Important</B>
<BOLD>Text</BOLD>Bold (same as B)<BOLD>Amount</BOLD>
<RIGHT>Text</RIGHT>Right align<RIGHT>$100</RIGHT>
<QR>Content</QR>QR code<QR>Order Link</QR>
<BARCODE>Content</BARCODE>Barcode<BARCODE>12345</BARCODE>
<CUT>Cut paper<CUT>

Solution 3: Mini Program Printing

In WeChat Mini Program environment, you can connect to printers via Bluetooth or use cloud printing services.

1. Bluetooth Printer Connection

export default async function ({ event, data }) {
try {
// 1. Initialize Bluetooth module
await wx.openBluetoothAdapter();

// 2. Start searching for Bluetooth devices
await wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
});

$w.utils.showToast({
title: "Searching for printers...",
icon: "loading",
duration: 2000,
});

// 3. Listen for Bluetooth device discovery
wx.onBluetoothDeviceFound((res) => {
console.log('Device found:', res.devices);
// Filter printers by device name or UUID
const printers = res.devices.filter(device =>
device.name && device.name.includes('Printer')
);

if (printers.length > 0) {
// Connect to first printer found
connectPrinter(printers[0].deviceId);
}
});
} catch (error) {
console.error('Bluetooth initialization failed:', error);
$w.utils.showToast({
title: "Bluetooth initialization failed",
icon: "error",
duration: 2000,
});
}
}

// Connect to printer
async function connectPrinter(deviceId) {
try {
await wx.createBLEConnection({ deviceId });

$w.utils.showToast({
title: "Printer connected successfully",
icon: "success",
duration: 2000,
});

// After successful connection, send print commands
// ...
} catch (error) {
console.error('Printer connection failed:', error);
}
}

2. Use Cloud Printing Service

Mini programs can also call the cloud function in Solution 2 for cloud printing.


Best Practices

1. Print Preview

Provide preview functionality before printing to let users confirm print content:

export default async function ({ event, data }) {
// Show print preview dialog
$w.utils.showModal({
title: 'Print Preview',
content: 'Confirm to print this order?',
success: (res) => {
if (res.confirm) {
// Execute print after user confirmation
window.print();
}
},
});
}

2. Batch Printing

Implement batch printing of multiple orders:

export default async function ({ event, data }) {
const selectedOrders = $w.dataList1.selectedItems; // Get selected orders

if (!selectedOrders || selectedOrders.length === 0) {
$w.utils.showToast({
title: "Please select orders to print",
icon: "error",
duration: 2000,
});
return;
}

// Batch call cloud function to print
const promises = selectedOrders.map(order =>
$w.cloud.callFunction({
name: 'printOrder',
data: { content: order },
})
);

try {
await Promise.all(promises);
$w.utils.showToast({
title: `Successfully printed ${selectedOrders.length} orders`,
icon: "success",
duration: 2000,
});
} catch (error) {
console.error('Batch print failed:', error);
$w.utils.showToast({
title: "Some orders failed to print",
icon: "error",
duration: 2000,
});
}
}

3. Print History

Save print records to database:

export default async function ({ event, data }) {
const app = await $w.cloud.getCloudInstance();
const db = app.database();

try {
// Save record before printing
await db.collection('print_history').add({
orderNo: data.orderNo,
printTime: new Date(),
printBy: $w.auth.currentUser.uid,
status: 'pending',
});

// Execute print
const result = await $w.cloud.callFunction({
name: 'printOrder',
data: { content: data },
});

// Update print status
await db.collection('print_history')
.where({ orderNo: data.orderNo })
.update({
status: result.success ? 'success' : 'failed',
result: result.data,
});
} catch (error) {
console.error('Failed to save print record:', error);
}
}

4. Error Handling

Comprehensive error handling mechanism:

export default async function ({ event, data }) {
try {
// Validate print data
if (!data || !data.orderNo) {
throw new Error('Incomplete order data');
}

// Check printer status (cloud printing)
const printerStatus = await checkPrinterStatus();
if (!printerStatus.online) {
throw new Error('Printer offline, please check device status');
}

// Execute print
const result = await $w.cloud.callFunction({
name: 'printOrder',
data: { content: data },
});

if (!result.success) {
throw new Error(result.error || 'Print failed');
}

$w.utils.showToast({
title: "Print successful",
icon: "success",
duration: 2000,
});
} catch (error) {
console.error('Print error:', error);

// Provide different prompts based on error type
let errorMessage = 'Print failed, please try again';
if (error.message.includes('offline')) {
errorMessage = 'Printer offline, please check device';
} else if (error.message.includes('data')) {
errorMessage = 'Order data error, please refresh and try again';
}

$w.utils.showToast({
title: errorMessage,
icon: "error",
duration: 3000,
});
}
}

// Check printer status
async function checkPrinterStatus() {
// Call cloud function to query printer status
const result = await $w.cloud.callFunction({
name: 'checkPrinter',
data: {},
});
return result.data;
}

FAQ

Q1: What if styles are lost when printing web pages?

A: Use @media print to define print-specific styles, and use targetStyles: ['*'] in print-js to preserve all styles.

Q2: How to implement silent printing (without dialog)?

A: For security reasons, browsers cannot implement silent printing directly. Use cloud printing services (such as Feie Cloud) for remote silent printing.

Q3: How to connect to network printers in mini programs?

A: Mini programs cannot directly connect to network printers. It's recommended to use cloud printing services or relay through a server.

Q4: What if print content shows garbled characters?

A: Check character encoding settings and ensure UTF-8 encoding is used. For cloud printing services, check the encoding requirements in the corresponding documentation.

Q5: How to implement print queue management?

A: Maintain a print queue in cloud functions, use database to record print task status, and process through scheduled tasks.