import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
import { PDFDocument, StandardFonts } from 'pdf-lib';
import React, { useEffect, useState } from 'react';
import { Button, Text, View } from 'react-native';
import fontkit from '@pdf-lib/fontkit';
import { decode, encode } from 'base-64';
import { Asset } from 'expo-asset';
// Comprobar si la función btoa (Base64 encode) no está disponible
// en el entorno global
if (!global.btoa) {
// Asignar la función de codificación Base64 (encode) al objeto
// global (global)
global.btoa = encode;
}
// Comprobar si la función atob (Base64 decode) no está disponible
// en el entorno global
if (!global.atob) {
// Asignar la función de decodificación Base64 (decode) al objeto
// global (global)
global.atob = decode;
}
export default function App() {
const [pdfUri, setPdfUri] = useState(null);
async function createAndSavePDF() {
try {
console.log('Generando el PDF...');
// Accediendo al archivo de fuente personalizada AlexBrush-Regular.ttf
// Comprobando si el directorio 'Fonts' en el sistema de
// archivos local existe.
if (!(await FileSystem.getInfoAsync(FileSystem.documentDirectory +
'Fonts')).exists) {
// Si no existe, crea el directorio 'Fonts' en el
// sistema de archivos local.
await FileSystem.makeDirectoryAsync(FileSystem.documentDirectory +
'Fonts');
}
// Comprobando si el archivo 'AlexBrush-Regular.ttf'
// en el directorio 'Fonts' existe.
if (!(await FileSystem.getInfoAsync(FileSystem.documentDirectory +
'Fonts/AlexBrush-Regular.ttf')).exists) {
// Si no existe, descarga el archivo 'AlexBrush-Regular.ttf'
// desde la ubicación
//de activos ('assets/fonts/CoconutOil.otf')
await FileSystem.downloadAsync(
Asset.fromModule(require('./assets/fonts/CoconutOil.otf')).uri,
FileSystem.documentDirectory + 'Fonts/AlexBrush-Regular.ttf'
);
}
// Accediendo a los datos binarios del archivo 'AlexBrush-Regular.ttf'.
const ttfBinary = await FileSystem.readAsStringAsync(FileSystem
.documentDirectory +
'Fonts/AlexBrush-Regular.ttf', {
encoding: FileSystem.EncodingType.Base64,
});
// Crea un nuevo documento PDF
const pdfDoc = await PDFDocument.create();
// Registro de fontkit
pdfDoc.registerFontkit(fontkit)
// Agregando una página al documento
const pageWidth = 8.5 * 72; // 8.5 pulgadas convertidas a puntos
const pageHeight = 11 * 72; // 11 pulgadas convertidas a puntos
const page = pdfDoc.addPage([pageWidth, pageHeight]);
// Registrando la fuente personalizada estandar
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
// Registrando la fuente personalizada externa
const customFont = await pdfDoc.embedFont(ttfBinary, {
custom: true,
});
// Agregando contenido al PDF
page.drawText('Hola, Mundo', {
x: 270,
y: 600,
size: 12,
font: font,
colorRgb: [0, 0, 0],
});
page.drawText('Cómo estás hoy', {
x: 250,
y: 560,
size: 24,
font: customFont, // Fuente personalizada
colorRgb: [0, 0, 0],
});
// Convertir el PDF a bytes
const pdfBytes = await pdfDoc.save();
// Guardar el archivo PDF en el almacenamiento local
const fileUri = `${FileSystem.documentDirectory}mi_archivo.pdf`;
// Convertir pdfBytes a una cadena Base64 utilizando btoa
const pdfBase64 = btoa(String.fromCharCode(...pdfBytes));
await FileSystem.writeAsStringAsync(fileUri, pdfBase64, {
encoding: FileSystem.EncodingType.Base64,
uri: fileUri,
});
console.log('El archivo PDF se ha generado y guardado.');
setPdfUri(fileUri);
} catch (error) {
console.error('Error al generar y guardar el PDF:', error);
}
};
const downloadPDF = async () => {
if (pdfUri) {
console.log('Ruta del archivo:', pdfUri);
const result = await Sharing.shareAsync(pdfUri);
if (result) {
const { status } = result;
if (status === 'done') {
console.log('El archivo PDF se descargó exitosamente.', status);
} else {
console.error('No se pudo completar la descarga del archivo PDF.', status);
}
} else {
console.error('No se pudo compartir el archivo PDF.');
console.error('Result: ', result);
}
} else {
console.error('El archivo PDF no existe.');
}
};
useEffect(() => {
createAndSavePDF();
}, []);
return (
<View style={{ flex: 1, justifyContent: 'center',
alignItems: 'center' }}>
<Text>Ejemplo de generación y descarga de PDF en React Native</Text>
<Button title="Guardar PDF"
onPress={downloadPDF}
/>
</View>
);
}
0 comentarios :
Publicar un comentario