forked from open-webui/open-webui
		
	refac: pdf generation
This commit is contained in:
		
							parent
							
								
									d001d7afb1
								
							
						
					
					
						commit
						81dbc65853
					
				
					 9 changed files with 104 additions and 51 deletions
				
			
		|  | @ -22,6 +22,32 @@ export const getGravatarUrl = async (email: string) => { | |||
| 	return res; | ||||
| }; | ||||
| 
 | ||||
| export const downloadChatAsPDF = async (chat: object) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const blob = await fetch(`${WEBUI_API_BASE_URL}/utils/pdf`, { | ||||
| 		method: 'POST', | ||||
| 		headers: { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}, | ||||
| 		body: JSON.stringify({ | ||||
| 			title: chat.title, | ||||
| 			messages: chat.messages | ||||
| 		}) | ||||
| 	}) | ||||
| 		.then(async (res) => { | ||||
| 			if (!res.ok) throw await res.json(); | ||||
| 			return res.blob(); | ||||
| 		}) | ||||
| 		.catch((err) => { | ||||
| 			console.log(err); | ||||
| 			error = err; | ||||
| 			return null; | ||||
| 		}); | ||||
| 
 | ||||
| 	return blob; | ||||
| }; | ||||
| 
 | ||||
| export const getHTMLFromMarkdown = async (md: string) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,8 @@ | |||
| 
 | ||||
| 	import Dropdown from '$lib/components/common/Dropdown.svelte'; | ||||
| 	import Tags from '$lib/components/common/Tags.svelte'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import { downloadChatAsPDF } from '$lib/apis/utils'; | ||||
| 
 | ||||
| 	export let shareEnabled: boolean = false; | ||||
| 	export let shareHandler: Function; | ||||
|  | @ -25,7 +27,7 @@ | |||
| 
 | ||||
| 	export let onClose: Function = () => {}; | ||||
| 
 | ||||
| 	const downloadChatAsTxt = async () => { | ||||
| 	const downloadTxt = async () => { | ||||
| 		const _chat = chat.chat; | ||||
| 		console.log('download', chat); | ||||
| 
 | ||||
|  | @ -40,54 +42,29 @@ | |||
| 		saveAs(blob, `chat-${_chat.title}.txt`); | ||||
| 	}; | ||||
| 
 | ||||
| 	const downloadChatAsPdf = async () => { | ||||
| 	const downloadPdf = async () => { | ||||
| 		const _chat = chat.chat; | ||||
| 		console.log('download', chat); | ||||
| 
 | ||||
| 		const doc = new jsPDF(); | ||||
| 		const blob = await downloadChatAsPDF(_chat); | ||||
| 
 | ||||
| 		// Initialize y-coordinate for text placement | ||||
| 		let yPos = 10; | ||||
| 		const pageHeight = doc.internal.pageSize.height; | ||||
| 		// Create a URL for the blob | ||||
| 		const url = window.URL.createObjectURL(blob); | ||||
| 
 | ||||
| 		// Function to check if new text exceeds the current page height | ||||
| 		function checkAndAddNewPage() { | ||||
| 			if (yPos > pageHeight - 10) { | ||||
| 				doc.addPage(); | ||||
| 				yPos = 10; // Reset yPos for the new page | ||||
| 			} | ||||
| 		} | ||||
| 		// Create a link element to trigger the download | ||||
| 		const a = document.createElement('a'); | ||||
| 		a.href = url; | ||||
| 		a.download = `chat-${_chat.title}.pdf`; | ||||
| 
 | ||||
| 		// Function to add text with specific style | ||||
| 		function addStyledText(text, isTitle = false) { | ||||
| 			// Set font style and size based on the parameters | ||||
| 			doc.setFont('helvetica', isTitle ? 'bold' : 'normal'); | ||||
| 			doc.setFontSize(isTitle ? 12 : 10); | ||||
| 		// Append the link to the body and click it programmatically | ||||
| 		document.body.appendChild(a); | ||||
| 		a.click(); | ||||
| 
 | ||||
| 			const textMargin = 7; | ||||
| 		// Remove the link from the body | ||||
| 		document.body.removeChild(a); | ||||
| 
 | ||||
| 			// Split text into lines to ensure it fits within the page width | ||||
| 			const lines = doc.splitTextToSize(text, 180); // Adjust the width as needed | ||||
| 
 | ||||
| 			lines.forEach((line) => { | ||||
| 				checkAndAddNewPage(); // Check if we need a new page before adding more text | ||||
| 				doc.text(line, 10, yPos); | ||||
| 				yPos += textMargin; // Increment yPos for the next line | ||||
| 			}); | ||||
| 
 | ||||
| 			// Add extra space after a block of text | ||||
| 			yPos += 2; | ||||
| 		} | ||||
| 
 | ||||
| 		_chat.messages.forEach((message, i) => { | ||||
| 			// Add user text in bold | ||||
| 			doc.setFont('helvetica', 'normal', 'bold'); | ||||
| 
 | ||||
| 			addStyledText(message.role.toUpperCase(), { isTitle: true }); | ||||
| 			addStyledText(message.content); | ||||
| 		}); | ||||
| 
 | ||||
| 		doc.save(`chat-${_chat.title}.pdf`); | ||||
| 		// Revoke the URL to release memory | ||||
| 		window.URL.revokeObjectURL(url); | ||||
| 	}; | ||||
| </script> | ||||
| 
 | ||||
|  | @ -193,7 +170,7 @@ | |||
| 						<DropdownMenu.Item | ||||
| 							class="flex gap-2 items-center px-3 py-2 text-sm  cursor-pointer dark:hover:bg-gray-850 rounded-md" | ||||
| 							on:click={() => { | ||||
| 								downloadChatAsTxt(); | ||||
| 								downloadTxt(); | ||||
| 							}} | ||||
| 						> | ||||
| 							<div class="flex items-center line-clamp-1">Plain text (.txt)</div> | ||||
|  | @ -202,7 +179,7 @@ | |||
| 						<DropdownMenu.Item | ||||
| 							class="flex gap-2 items-center px-3 py-2 text-sm  cursor-pointer dark:hover:bg-gray-850 rounded-md" | ||||
| 							on:click={() => { | ||||
| 								downloadChatAsPdf(); | ||||
| 								downloadPdf(); | ||||
| 							}} | ||||
| 						> | ||||
| 							<div class="flex items-center line-clamp-1">PDF document (.pdf)</div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek