word转pdf问题修复

This commit is contained in:
andy committed 2026-09-11 16:18:44 +08:00
1 parent a4d55a5c55
commit 712ec51d68
5 files changed
+158

No files matched your search

+5
View File
@@ -237,6 +237,11 @@ export async function convertDocumentToPdf(
'--nolockcheck',
'--nofirststartwizard',
`-env:UserInstallation=${pathToFileURL(profileDirectory).href}`,
// Default HTML import can lose the first paragraph and emit a blank page
// in LibreOffice 7.4. Use Writer's HTML importer for HTML-in-DOC as well.
...(isHtmlDocument(inputName, input.contentType, input.content)
? ['--infilter=HTML (StarWriter)']
: []),
'--convert-to',
`pdf:${PDF_EXPORT_FILTER}`,
'--outdir',
@@ -46,6 +46,55 @@ test('conversion failure falls back to the source file', async () => {
assert.deepEqual(result.content, content);
});
test('PDF conversion selects Writer HTML import only for HTML documents', {
skip: process.platform === 'win32' ? 'Unix fake converter fixture is not executable through Windows execFile.' : false
}, async (t) => {
const temporaryDirectory = await mkdtemp(join(tmpdir(), 'ltjt-converter-import-test-'));
const converterPath = join(temporaryDirectory, 'fake-soffice.sh');
await writeFile(converterPath, [
'#!/bin/sh',
'outdir=""',
'next_is_outdir=0',
'for arg in "$@"; do',
' if [ "$next_is_outdir" = "1" ]; then outdir="$arg"; next_is_outdir=0; continue; fi',
' if [ "$arg" = "--outdir" ]; then next_is_outdir=1; fi',
'done',
'printf "%s\\n" "%PDF-1.7" "$@" > "$outdir/team.pdf"'
].join('\n'), { mode: 0o700 });
await chmod(converterPath, 0o700);
const cases = [
{ name: 'ERP Word HTML with vendor MIME', fileName: 'team.doc', contentType: 'application/vnd.ms-word; Charset=UTF-8', content: '\uFEFF\r\n<html><body><p>确认书标题</p><p>正文</p></body></html>', html: true },
{ name: 'HTML doctype in a Word file', fileName: 'team.doc', contentType: 'application/msword', content: '<!DOCTYPE HTML><HTML><BODY>确认书</BODY></HTML>', html: true },
{ name: 'legacy body-only Word HTML', fileName: 'team.doc', contentType: 'application/msword', content: '<body><p>确认书</p></body>', html: true },
{ name: 'HTML extension', fileName: 'team.html', contentType: 'application/octet-stream', content: '<p>确认书</p>', html: true },
{ name: 'HTML MIME without extension', fileName: 'team', contentType: 'text/html; charset=utf-8', content: '<p>确认书</p>', html: true },
{ name: 'binary Word', fileName: 'team.doc', contentType: 'application/msword', content: Buffer.from([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1]), html: false },
{ name: 'DOCX package', fileName: 'team.docx', contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', content: Buffer.from([0x50, 0x4b, 0x03, 0x04]), html: false },
{ name: 'RTF', fileName: 'team.rtf', contentType: 'application/rtf', content: '{\\rtf1 Confirmation}', html: false }
];
try {
for (const item of cases) {
await t.test(item.name, async () => {
const result = await convertDocumentToPdf(testConfig(converterPath), {
fileName: item.fileName,
contentType: item.contentType,
content: Buffer.from(item.content),
maxBytes: 10_000
});
assert.equal(result.converted, true);
const args = result.content.toString('utf8').split('\n');
assert.deepEqual(
args.filter((arg) => arg.startsWith('--infilter')),
item.html ? ['--infilter=HTML (StarWriter)'] : []
);
assert.ok(args.includes('pdf:writer_pdf_Export'));
});
}
} finally {
await rm(temporaryDirectory, { recursive: true, force: true });
}
});
test('a valid converter output replaces the source with a PDF', {
skip: process.platform === 'win32' ? 'Unix fake converter fixture is not executable through Windows execFile.' : false
}, async () => {