package com.cqbb.common.utils.poi;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cqbb.common.config.BBKJConfig;
import org.apache.commons.io.IOUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import java.io.*;
import java.math.BigInteger;
import java.util.Base64;
/**
* 我这里是循环调用的,所以在上一级创建的 XWPFDocument 对象 项目框架用的若依springboot vue
* 参数 title 为当前段落的文本,JSONArray为表格的内容
*JSONArray array = new JSONArray();
*JSONObject object = new JSONObject();
*object.put("question", bbQuestion.getBbQuestion());//问题
*object.put("type", bbQuestion.getBbType());//类型
*object.put("answer","是");//答案
*array.add(object);
*/
public class ExportWordUtil {
public static void exportManyWord(XWPFDocument doc, String title, JSONArray dataArray){
XWPFParagraph p = doc.createParagraph();// 新建一个段落
p.setAlignment(ParagraphAlignment.CENTER);
CTSpacing spacing = p.getCTP().addNewPPr().addNewSpacing();
spacing.setBefore(BigInteger.valueOf(4 * 240)); // 240 Twips = 1 磅 = 1/72 英寸
XWPFRun r = p.createRun();//创建段落文本
r.setText(title);
r.setBold(true);//设置为粗体
r.setText("\r");
// 行(9) 列
XWPFTable table = doc.createTable(9, 4);//创建一个表格
table.setWidth("100%");
mergeCellsInRow(0, 0, 1, table);
mergeCellsInRow(0, 2, 3, table);
mergeCellsInRow(1, 0, 1, table);
mergeCellsInRow(1, 2, 3, table);
mergeCellsInRow(2, 0, 1, table);
mergeCellsInRow(2, 2, 3, table);
mergeCellsInRow(3, 0, 1, table);
mergeCellsInRow(3, 2, 3, table);
mergeCellsInRow(4, 0, 3, table);
mergeCellsInRow(5, 0, 3, table);
mergeCellsInRow(6, 0, 3, table);
table.getRow(0).getCell(0).setText("填报日期");
table.getRow(0).getCell(0).setWidth("50%");
XWPFParagraph paragraph00 = table.getRow(0).getCell(0).getParagraphArray(0);
paragraph00.setAlignment(ParagraphAlignment.CENTER);
table.getRow(0).getCell(2).setText("配送商业");
table.getRow(0).getCell(2).setWidth("50%");
XWPFParagraph paragraph02 = table.getRow(0).getCell(2).getParagraphArray(0);
paragraph02.setAlignment(ParagraphAlignment.CENTER);
table.getRow(1).getCell(0).setText("");
table.getRow(1).getCell(0).setWidth("50%");
table.getRow(1).getCell(2).setText("");
table.getRow(1).getCell(2).setWidth("50%");
table.getRow(2).getCell(0).setText("产品名称");
table.getRow(2).getCell(0).setWidth("50%");
XWPFParagraph paragraph20 = table.getRow(2).getCell(0).getParagraphArray(0);
paragraph20.setAlignment(ParagraphAlignment.CENTER);
table.getRow(2).getCell(2).setText("规格");
table.getRow(2).getCell(2).setWidth("50%");
XWPFParagraph paragraph22 = table.getRow(2).getCell(2).getParagraphArray(0);
paragraph22.setAlignment(ParagraphAlignment.CENTER);
table.getRow(3).getCell(0).setText("");
table.getRow(3).getCell(0).setWidth("50%");
table.getRow(3).getCell(2).setText("");
table.getRow(3).getCell(2).setWidth("50%");
table.getRow(4).getCell(0).setWidth("100%");
XWPFTableCell cell4 = table.getRow(4).getCell(0);
//问卷内容
for (int i = 0; i < dataArray.size(); i++) {
JSONObject object = dataArray.getJSONObject(i);
cell4.setText("\r");
cell4.setText(" " + (i + 1)+ "、" + object.getString("question") + "\r");
if (object.getInteger("type") == 7){
XWPFParagraph paragraph = cell4.addParagraph();
XWPFRun run = paragraph.createRun();
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(object.getString("answer").replace("/profile",""));
run.addPicture(fileInputStream,Document.PICTURE_TYPE_PNG, "TEST", Units.toEMU(200), Units.toEMU(100));
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 2. 获取到图片数据
// CTDrawing drawing = run.getCTR().getDrawingArray(0);
// CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
// //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
// CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "TEST1",
// Units.toEMU(100), Units.toEMU(30),//图片大小
// Units.toEMU(50), Units.toEMU(0), false);//相对当前段落位置 需要计算段落已有内容的左偏移
// drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
// drawing.removeInline(0);//删除行内属性
} else {
cell4.setText("\r");
cell4.setText(" " + object.getString("answer"));
cell4.setText("\r");
}
}
table.getRow(5).getCell(0).setText("有何建议");
table.getRow(5).getCell(0).setWidth("100%");
XWPFTableCell cell = table.getRow(5).getCell(0);
cell.addParagraph();//换行
cell.addParagraph();
cell.addParagraph();
table.getRow(6).getCell(0).setText("(请根据实际情况勾选)");
table.getRow(6).getCell(0).setWidth("100%");
table.getRow(7).getCell(0).setText("填报地区:");
table.getRow(7).getCell(2).setText("填报时间:");
table.getRow(7).getCell(0).setWidth("25%");
table.getRow(7).getCell(1).setWidth("25%");
table.getRow(7).getCell(2).setWidth("25%");
table.getRow(7).getCell(3).setWidth("25%");
table.getRow(8).getCell(0).setText("受访人:");
table.getRow(8).getCell(2).setText("访问人:");
table.getRow(8).getCell(0).setWidth("25%");
table.getRow(8).getCell(1).setWidth("25%");
table.getRow(8).getCell(2).setWidth("25%");
table.getRow(8).getCell(3).setWidth("25%");
}
private static void mergeCellsInRow(int row, int fromCol, int toCol, XWPFTable table) {
for (int col = fromCol; col <= toCol; col++) {
table.getRow(row).getCell(col).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
if (col == fromCol) {
table.getRow(row).getCell(col).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
table.getRow(row).getCell(col).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
private static String convertFileToBase64(String filePath) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
byte[] fileBytes = new byte[fileInputStream.available()];
fileInputStream.read(fileBytes);
return Base64.getEncoder().encodeToString(fileBytes);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @param ctGraphicalObject 图片数据
* @param deskFileName 图片描述
* @param width 宽
* @param height 高
* @param leftOffset 水平偏移 left
* @param topOffset 垂直偏移 top
* @param behind 文字上方,文字下方
* @return
* @throws Exception
*/
public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
String deskFileName, int width, int height,
int leftOffset, int topOffset, boolean behind) {
String anchorXML =
"<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
+ "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
+ "<wp:simplePos x=\"0\" y=\"0\"/>"
+ "<wp:positionH relativeFrom=\"column\">"
+ "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
+ "</wp:positionH>"
+ "<wp:positionV relativeFrom=\"paragraph\">"
+ "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
"</wp:positionV>"
+ "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
+ "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
+ "<wp:wrapNone/>"
+ "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
+ "</wp:anchor>";
CTDrawing drawing = null;
try {
drawing = CTDrawing.Factory.parse(anchorXML);
} catch (XmlException e) {
e.printStackTrace();
}
CTAnchor anchor = drawing.getAnchorArray(0);
anchor.setGraphic(ctGraphicalObject);
return anchor;
}
}
最后生成的结果,欢迎指正优化