ヤ℡君常笑╰♪ 2025-12-30 13:58 采纳率: 0%
浏览 2

jsp图片放入word乱码问题怎么解决



<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.io.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="weaver.conn.RecordSet" %>
<%@ page import="weaver.general.Util" %>
<%@ page import="net.sf.json.JSONObject" %>
<%@ page import="net.sf.json.JSONArray" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="org.jfree.chart.ChartFactory" %>
<%@ page import="org.jfree.chart.JFreeChart" %>
<%@ page import="org.jfree.chart.plot.PlotOrientation" %>
<%@ page import="org.jfree.chart.ChartUtilities" %>
<%@ page import="org.jfree.data.category.DefaultCategoryDataset" %>
<%@ page import="org.apache.poi.xwpf.usermodel.XWPFDocument" %>
<%@ page import="org.apache.poi.xwpf.usermodel.XWPFParagraph" %>
<%@ page import="org.apache.poi.xwpf.usermodel.XWPFRun" %>
<%@ page import="org.apache.poi.util.Units" %>
<%
    // ===== 生成Word文档逻辑(直接从图片路径读取) =====
    String generateWord = Util.null2String(request.getParameter("generateWord"));
    if (!generateWord.isEmpty()) {
        try {
            String appRoot = application.getRealPath("/");
            String chartFilePath = appRoot + "charts/" + generateWord;
            File chartFile = new File(chartFilePath);

            if (!chartFile.exists()) {
                response.sendError(404, "图表文件不存在: " + generateWord);
                return;
            }

            // 创建Word文档
            XWPFDocument document = new XWPFDocument();

            // 添加标题
            XWPFParagraph title = document.createParagraph();
            XWPFRun titleRun = title.createRun();
            titleRun.setText("考勤异常统计报告");
            titleRun.setBold(true);
            titleRun.setFontSize(16);
            titleRun.setFontFamily("宋体");
            titleRun.addBreak();

            // 添加图片(直接从路径读取)
            XWPFParagraph paragraph = document.createParagraph();
            paragraph.setAlignment(org.apache.poi.xwpf.usermodel.ParagraphAlignment.CENTER);
            XWPFRun run = paragraph.createRun();

            // 读取图片数据为字节数组,避免编码问题
            byte[] pictureData = new byte[(int) chartFile.length()];
            try (FileInputStream fis = new FileInputStream(chartFile)) {
                fis.read(pictureData);
                // 使用字节数组创建输入流
                try (ByteArrayInputStream bais = new ByteArrayInputStream(pictureData)) {
                    run.addPicture(bais, XWPFDocument.PICTURE_TYPE_PNG, chartFile.getName(), Units.toEMU(500), Units.toEMU(300));
                }
            }

            // 添加说明文字
            XWPFParagraph desc = document.createParagraph();
            desc.setAlignment(org.apache.poi.xwpf.usermodel.ParagraphAlignment.CENTER);
            XWPFRun descRun = desc.createRun();
            descRun.setText("图1:考勤异常统计折线图");
            descRun.setFontFamily("宋体");
            descRun.addBreak();

            // 设置响应头,下载Word文档
            response.reset();
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            String wordFileName = "考勤统计报告_" + System.currentTimeMillis() + ".docx";
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(wordFileName, "UTF-8"));

            // 输出Word文档
            OutputStream outStream = response.getOutputStream();
            document.write(outStream);
            outStream.flush();
            outStream.close();
            document.close();
            return;
        } catch (Exception e) {
            e.printStackTrace();
            out.print("{\"code\":500,\"msg\":\"生成Word文档失败:" + e.getMessage() + "\"}");
            return;
        }
    }

    // ===== 数据查询逻辑 =====
    RecordSet rs = new RecordSet();
    String departmentIds = Util.null2String(request.getParameter("departmentId"));
    JSONObject returnObject = new JSONObject();
    JSONArray dataArray = new JSONArray();

    try {
        if (departmentIds.isEmpty()) {
            returnObject.put("code", 500);
            returnObject.put("msg", "参数不能为空!");
        } else if (!departmentIds.matches("^\\d+(,\\d+)*$")) {
            returnObject.put("code", 500);
            returnObject.put("msg", "参数格式错误!");
        } else {
            String[] deptIdArray = departmentIds.split(",");
            String inCondition = String.join(",", deptIdArray);

            String sql = "SELECT " +
                    "departmentid," +
                    "COUNT(DISTINCT CASE WHEN A.belate > 0 THEN A.resourceid END) AS late_persons," +
                    "COALESCE(SUM(A.belate), 0) AS late_count," +
                    "COUNT(DISTINCT CASE WHEN A.leaveeearly > 0 THEN A.resourceid END) AS early_leave_persons," +
                    "COALESCE(SUM(A.leaveeearly), 0) AS early_leave_count," +
                    "COUNT(DISTINCT CASE WHEN A.absenteeism > 0 THEN A.resourceid END) AS absenteeism_persons," +
                    "COALESCE(SUM(A.absenteeism), 0) AS absenteeism_count," +
                    "COALESCE(SUM(A.workdays), 0) AS scheduled_work_days," +
                    "COALESCE(SUM(A.attendancedays), 0) AS actual_work_days " +
                    "FROM kq_format_total A " +
                    "WHERE departmentid IN (" + inCondition + ") " +
                    "GROUP BY departmentid";

            rs.executeSql(sql);

            while (rs.next()) {
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("departmentId", rs.getString("departmentid"));
                dataMap.put("latePersons", rs.getString("late_persons"));
                dataMap.put("lateCount", rs.getString("late_count"));
                dataMap.put("earlyLeavePersons", rs.getString("early_leave_persons"));
                dataMap.put("earlyLeaveCount", rs.getString("early_leave_count"));
                dataMap.put("absenteeismPersons", rs.getString("absenteeism_persons"));
                dataMap.put("absenteeismCount", rs.getString("absenteeism_count"));
                dataMap.put("scheduledWorkDays", rs.getString("scheduled_work_days"));
                dataMap.put("actualWorkDays", rs.getString("actual_work_days"));

                dataArray.add(JSONObject.fromObject(dataMap));
            }

            if (dataArray.size() > 0) {
                returnObject.put("code", 200);
                returnObject.put("msg", "查询成功!共找到" + dataArray.size() + "条数据");
                returnObject.put("data", dataArray);

                // ===== 生成折线图 =====
                String appRoot = application.getRealPath("/");
                String chartDirPath = appRoot + "charts/";
                File chartDir = new File(chartDirPath);
                if (!chartDir.exists()) {
                    chartDir.mkdirs();
                }

                DefaultCategoryDataset dataset = new DefaultCategoryDataset();
                for (int i = 0; i < dataArray.size(); i++) {
                    JSONObject dept = dataArray.getJSONObject(i);
                    String deptId = dept.getString("departmentId");
                    int latePersons = Integer.parseInt(dept.getString("latePersons"));
                    int earlyLeavePersons = Integer.parseInt(dept.getString("earlyLeavePersons"));
                    int absenteeismPersons = Integer.parseInt(dept.getString("absenteeismPersons"));

                    dataset.addValue(latePersons, "迟到人次", deptId);
                    dataset.addValue(earlyLeavePersons, "早退人次", deptId);
                    dataset.addValue(absenteeismPersons, "缺勤人次", deptId);
                }

                JFreeChart chart = ChartFactory.createLineChart(
                        "考勤异常统计",
                        "部门ID",
                        "人次数",
                        dataset,
                        PlotOrientation.VERTICAL,
                        true, true, false
                );

                String fileName = "attendance_chart_" + System.currentTimeMillis() + ".png";
                String fullPath = chartDirPath + fileName;
                ChartUtilities.saveChartAsPNG(new File(fullPath), chart, 800, 600);

                returnObject.put("chartUrl", "charts/" + fileName);

                // 生成Word文档按钮(直接链接到当前JSP,带generateWord参数)
                String currentJspName = request.getRequestURI().substring(request.getRequestURI().lastIndexOf('/') + 1);
                String wordButton = "<a href='" + currentJspName + "?generateWord=" + fileName + "' download='考勤统计报告.docx'>生成Word报告</a>";
                returnObject.put("wordButton", wordButton);

            } else {
                returnObject.put("code", 500);
                returnObject.put("msg", "未查询到数据!部门ID列表:" + departmentIds);
                returnObject.put("data", dataArray);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        returnObject.put("code", 500);
        returnObject.put("msg", "系统异常:" + e.getMessage());
        returnObject.put("data", dataArray);
    }

    // 输出JSON
    out.print(returnObject.toString());
%>

图片放入word出现乱码问题

  • 写回答

2条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-12-30 14:04
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 从提供的代码片段来看,问题可能出在将JSP中的图片放入Word时出现乱码。这可能涉及到文件读取、编码转换以及Word文件格式处理等多方面。比如图片读取时编码是否正确,写入Word时编码是否匹配等。
    2. 解决方案:
      - 首先,读取图片文件时要确保以正确的编码读取。如果图片文件本身是二进制文件,不需要进行编码转换,但要注意读取方式。
      - 然后,在将图片内容写入Word时,需要考虑Word文件的格式和编码。通常可以使用Apache POI库来操作Word文件。以下是一个简单的示例代码,假设使用XWPF来操作Word文件:
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFPictureData;
    import org.apache.poi.xwpf.usermodel.XWPFPictureRun;
    
    public class ImageToWord {
        public static void main(String[] args) {
            try {
                // 读取Word文件
                XWPFDocument document = new XWPFDocument(new FileInputStream("yourWordFile.docx"));
                // 读取图片文件
                InputStream imageStream = new FileInputStream("yourImageFile.jpg");
                byte[] imageBytes = new byte[imageStream.available()];
                imageStream.read(imageBytes);
                imageStream.close();
                // 添加图片到Word
                XWPFPictureData pictureData = document.addPictureData(imageBytes, XWPFDocument.PICTURE_TYPE_JPEG);
                XWPFPictureRun pictureRun = document.createParagraph().createRun().addPicture(pictureData);
                // 保存修改后的Word文件
                FileOutputStream out = new FileOutputStream("newWordFile.docx");
                document.write(out);
                out.close();
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 在上述代码中,首先读取Word文件和图片文件,将图片字节数组添加到Word文件中并保存。这里在读取图片文件时没有进行编码转换,因为图片本身是二进制数据。
      3. 多种解决方案的优缺点:
    • 使用Apache POI库
      • 优点:功能强大,能直接操作Word文件,提供了丰富的API来处理文档内容、样式、图片等。代码相对清晰,易于理解和扩展。
      • 缺点:对于复杂的Word文件格式和功能,可能需要深入学习其API,配置相关依赖可能会比较繁琐。
    • 使用其他第三方库
      • 优点:可能有更简洁的方式处理特定场景,有些库可能针对特定需求进行了优化。
      • 缺点:学习成本和维护成本可能较高,不同库的功能和适用场景有限,可能需要根据具体需求选择合适的库。
        4. 总结:
    • 解决JSP图片放入Word乱码问题,关键在于正确读取图片文件和合理写入Word文件。使用合适的库如Apache POI来处理Word文件操作,可以方便地实现图片添加且避免乱码问题。同时要根据实际需求和项目情况选择合适的解决方案,权衡不同方案的优缺点。

    请注意,上述代码中的文件路径需要根据实际情况进行修改。此外,实际应用中可能还需要考虑更多的细节,如图片的大小调整、Word文件的样式设置等。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月30日