jeecgboot/JeecgBoot · error · JeecgBootException

生成word文档失败: {message}

Error message

生成word文档失败: {message}

What it means

generateWord() generates a document from a template + data map and streams the .docx to the response. Any exception (template not found by id/code, generateWordFromTpl failure, client-disconnect IOException) is wrapped as JeecgBootException with the cause message.

Source

Thrown at jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/wordtpl/controller/AigcWordTemplateController.java:240

            template = eoaWordTemplateService.getOne(Wrappers.lambdaQuery(AigcWordTemplate.class)
                    .eq(AigcWordTemplate::getCode, wordTplGenDTO.getTemplateCode()));
        }
        AssertUtils.assertNotEmpty("未找到对应的模版", template);

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
             BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());) {
            eoaWordTemplateService.generateWordFromTpl(wordTplGenDTO, outputStream);
            String fileName = template.getName();
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.addHeader("Content-Disposition", "attachment;filename=" + encodedFileName + ".docx");
            response.addHeader("filename", encodedFileName + ".docx");
            byte[] bytes = outputStream.toByteArray();
            response.setHeader("Content-Length", String.valueOf(bytes.length));
            bos.write(bytes);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new JeecgBootException("生成word文档失败: " + e.getMessage(), e);
        }
    }

}

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Read the cause stacktrace in the log.
  2. Confirm the template exists (by id, or by code via the lambdaQuery).
  3. Reproduce generateWordFromTpl with the same DTO to isolate poi-tl vs streaming.
  4. For ClientAbortException, treat as client disconnect.
Defensive patterns

Strategy: validation

Validate before calling

// confirm template resolves before generating
AigcWordTemplate template;
if (oConvertUtils.isNotEmpty(wordTplGenDTO.getTemplateId())) {
    template = eoaWordTemplateService.getById(wordTplGenDTO.getTemplateId());
} else {
    template = eoaWordTemplateService.getOne(Wrappers.lambdaQuery(AigcWordTemplate.class)
        .eq(AigcWordTemplate::getCode, wordTplGenDTO.getTemplateCode()));
}
if (template == null) { response.sendError(404, "未找到对应的模版"); return; }

Try / catch

try { ... } catch (java.io.IOException clientEx) {
    log.warn("客户端断开,生成word下载中止", clientEx);
} catch (Exception e) {
    throw new JeecgBootException("生成word文档失败: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: template lookup returns null (assertNotEmpty fires first, but a stale id can still slip through); eoaWordTemplateService.generateWordFromTpl throws (see error 127); response.getOutputStream() fails on client abort.

Common situations: Invalid templateId or templateCode; data map keys don't match template placeholders; client cancels the download; template references an inaccessible image.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/a57d4657590d726e. Report an issue: GitHub.