Files
QOffice/src/io/desktopOfficeFiles.ts
T
Курнат Андрей 9bf4dd3672 Initial QOffice implementation
2026-06-01 05:31:05 +03:00

57 lines
2.0 KiB
TypeScript

export type OfficeFileKind = "docx" | "xlsx" | "pptx" | "eml" | "mail";
const mimeTypes: Record<OfficeFileKind, string> = {
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
eml: "message/rfc822",
mail: "application/octet-stream"
};
export function isDesktopOfficeBridgeAvailable() {
return Boolean(window.qoffice?.isDesktop && window.qoffice.openOfficeFile && window.qoffice.saveOfficeFile);
}
export async function openDesktopOfficeFile(kind: OfficeFileKind): Promise<File | null> {
const result = await window.qoffice?.openOfficeFile?.(kind);
if (!result || result.canceled) {
return null;
}
if (!result.base64Data) {
throw new Error("Desktop-оболочка QOffice не вернула данные файла.");
}
return new File([base64ToBytes(result.base64Data)], result.fileName ?? `qoffice.${kind}`, {
type: mimeTypes[kind]
});
}
export async function saveDesktopOfficeFile(kind: OfficeFileKind, defaultFileName: string, blob: Blob) {
const bridge = window.qoffice;
if (!bridge?.saveOfficeFile) {
throw new Error("Desktop-оболочка QOffice недоступна.");
}
const base64Data = bytesToBase64(new Uint8Array(await blob.arrayBuffer()));
return bridge.saveOfficeFile(kind, defaultFileName, base64Data);
}
export function bytesToBase64(bytes: Uint8Array) {
let binary = "";
const chunkSize = 0x8000;
for (let index = 0; index < bytes.length; index += chunkSize) {
binary += String.fromCharCode(...bytes.slice(index, index + chunkSize));
}
return btoa(binary);
}
export function base64ToBytes(base64Data: string) {
const binary = atob(base64Data);
const bytes = new Uint8Array(binary.length);
for (let index = 0; index < binary.length; index += 1) {
bytes[index] = binary.charCodeAt(index);
}
return bytes;
}