poi操作word,写入一个图片,并且设置其大小,以及图片和base64之间的互相转换,以及表格内容替换和插入

一:word处理图片功能,插入一张图片,并且设置大小,然后添加一段文字,测试图片和文字之间的换行效果:

public class ImgToWordTest {
	public static void main(String[] args) throws Exception {
	        writeToWord();
	}

	 /**
     * Word中写入图片示例
     * @throws Exception
     */
	public static void writeToWord() throws Exception {
        FileOutputStream fos = new FileOutputStream("D:\\downWord\\temp.docx");
        String imgPath = "D:\\downWord\\test\\tianlong.png";   // 图片路径

        //创建文档对象
        XWPFDocument document = new XWPFDocument();
        //创建段落对象
        XWPFParagraph paragraph = document.createParagraph();
        //创建文本对象(今天的主角:XWPFRun----一段文本对象(就是一段文字))
        XWPFRun run = paragraph.createRun();//这里用的段落里的XWPFRun


        //第一种,用base64字符串解码后的base64字节数组
        File file = new File(imgPath);
        String png = getImageStr(file, "png");
        String codedata = png.substring(png.indexOf(",") + 1);
        byte[] bytes = new BASE64Decoder().decodeBuffer(codedata);
        String picId = document.addPictureData(bytes, CustomXWPFDocument.PICTURE_TYPE_PNG);
        //第二种用流的方式
//      FileInputStream fileInputStream = new FileInputStream(imgPath);
//      String picId = document.addPictureData(fileInputStream, CustomXWPFDocument.PICTURE_TYPE_PNG);
        WordocxUtil.addPictureToRun(run,picId,CustomXWPFDocument.PICTURE_TYPE_PNG,600,600);


        //当然也可以用表格里面的XWPFRun
//        InputStream inStream = WorderToNewWordUtils.class.getClassLoader().getResourceAsStream("templates/工具杀毒检测记录表.docx");
//        XWPFDocument doc = new XWPFDocument(inStream);
//        List<XWPFTable> xwpfTables = doc.getTables();
//        XWPFTable xwpfTable = xwpfTables.get(4);//这里假设拿下标为四的表
//        List<XWPFTableRow> rows = xwpfTable.getRows();
//        XWPFTableRow xwpfTableRow = rows.get(4);//这里假设拿下标为四的行
//        List<XWPFTableCell> tableCells = xwpfTableRow.getTableCells();
//        XWPFTableCell xwpfTableCell = tableCells.get(1);//这里假设拿下标为一的列
//        List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();
//        XWPFParagraph xwpfParagraph = paragraphs.get(0);//这里假设拿下标为0的段落
//        XWPFRun run2 = xwpfParagraph.createRun();//这个段落里创建一段文字
//        String picId2 = document.addPictureData(bytes, CustomXWPFDocument.PICTURE_TYPE_PNG);
//        WordocxUtil.addPictureToRun(run2,picId2,CustomXWPFDocument.PICTURE_TYPE_PNG,600,600);


        //run.addBreak(BreakType.COLUMN)----这里无论是PAGE,还是这个COLUMN,都是换页的效果;
        run.addCarriageReturn();//----加一个换行符
        //默认:宋体(wps)/等线(office2016) 5号 两端对齐 单倍间距
        run.setText("舜发于畎亩之中, 傅说举于版筑之间, 胶鬲举于鱼盐之中, 管夷吾举于士,孙叔敖举于海,百里奚举于市。故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。\n");
        run.addCarriageReturn();//----加一个换行符
        run.setText("人恒过,然后能改,困于心,衡于虑,而后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡,然后知生于忧患而死于安乐也。");
        run.setBold(false);//加粗
        run.setColor("BED4F1");//设置颜色--十六进制
        run.setDoubleStrikethrough(false);//双删除线
        run.setEmbossed(false);//浮雕字体----效果和印记(悬浮阴影)类似
        //run.setFontFamily("宋体");
        run.setFontSize(14);//字体大小
        run.setImprinted(false);//印迹(悬浮阴影)---效果和浮雕类似
        run.setItalic(false);//斜体(字体倾斜)
        run.setShadow(true);//阴影---稍微有点效果(阴影不明显)
        run.setStrikeThrough(false);//单删除线(新的替换Strike)
        //run.setSubscript(VerticalAlign.SUBSCRIPT);//下标(吧当前这个run变成下标)---枚举
        //run.setUnderline(UnderlinePatterns.DASH_LONG);//各种类型的下划线(枚举)



        //ImageUtils.writeImage(run, imgPath)//这是一开始的时候,直接写了一张图片;
        document.write(fos);
        System.out.println("=========Word文件生成成功==========");

        //fileInputStream.close();
        fos.close();
    }

	//图片转化成base64字符串
    public static String getImageStr(File file, String fileType) throws IOException {
        String fileContentBase64 = null;
        String base64Str = "data:" + fileType + ";base64,";
        String content = null;
        //将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(file);
            data = new byte[in.available()];
            in.read(data);
            in.close();
            //对字节数组Base64编码
            if (data == null || data.length == 0) {
                return null;
            }
            //content = Base64.encodeBytes(data);
            content = new BASE64Encoder().encode(data);
            if (content == null || "".equals(content)) {
                return null;
            }
            fileContentBase64 = base64Str + content;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                in.close();
            }
        }
        return fileContentBase64;
    }
}

上文中用到的工具类:

/**
 * 报告导出
 */
@Component
public class WordocxUtil {
	public static void addPictureToRun(XWPFRun run,String blipId,int id,int width, int height){
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;

        CTInline inline =run.getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try {
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch(XmlException xe) {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
	
	/*
        创建FileItem
         */
    public FileItem createFileItem(File file, String fieldName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }
    public static void closeStream(InputStream inStream) {
        try {
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void writer(XWPFDocument doc, String outSrc, Map<String,Object> map) {

                /**
                 * 替换段落中指定的文本
                 */
                for(XWPFParagraph p : doc.getParagraphs()){
                    List<XWPFRun> runs = p.getRuns();
                    if(runs != null){
                        for(XWPFRun r : runs){
                            //需要替换的文本
                            String text = r.getText(0);
                            //替换指定的文本
                            for(String key : map.keySet()){
                                if(text != null && text.equals(key)){
                                    //替换的时候要注意,setText是有两个参数的
                                    //第一个是替换的文本,第二个是从哪里开始替换
                                    //0是替换全部,如果不设置那么默认就是从原文字
                                    //结尾开始追加
                                    r.setText((String)map.get(key),0);
                                }
                            }
                        }
                    }
                }
                /**
                 * 替换表格中指定的文字
                 */
                for(XWPFTable tab : doc.getTables()){
                    for(XWPFTableRow row : tab.getRows()){
                        for(XWPFTableCell cell : row.getTableCells()){
                            //注意,getParagraphs一定不能漏掉
                            //因为一个表格里面可能会有多个需要替换的文字
                            //如果没有这个步骤那么文字会替换不了
                            for(XWPFParagraph p : cell.getParagraphs()){
                                for(XWPFRun r : p.getRuns()){
                                    String text = r.getText(0);
                                    for(String key : map.keySet()){
                                        if(text!=null){
                                            if(text.equals(key)){
                                                r.setText((String)map.get(text),0);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }


}

二:word表格字段替换和插入功能示例:


    //用户资料使用登记表----controller层
    //@Scheduled(fixedDelay = 600 * 1000)
    @GetMapping("/tEvaluationQueues/upRegister")
    public void getUpRegister(){
        log.debug("REST request to get upRegister");
        tEvaluationQueueService.getUpRegister();
    }
	
	//service层
	void getUpRegister();

	//serviceImpl层
	//用户资料使用登记表
	@Override
	public void getUpRegister() {
		TEvaluationQueueExample example = new TEvaluationQueueExample();
		TEvaluationQueueExample.Criteria criteria = example.createCriteria();
		criteria.andStatusEqualTo(0);//未开始   后期还得一个各自自己的文件标记 6-1
		criteria.andEvaluationTypeIdEqualTo("6-1");
		List<TEvaluationQueue> que = tEvaluationQueueRepository.selectByExample(example);
		if (que!=null&&que.size()>0){
			for (TEvaluationQueue tEvaluationQueue : que) {
				//进入循环,更改状态为1----执行中
				tEvaluationQueue.setStatus(1);//只改动了status,其他的还是tEvaluationQueue的原值
				tEvaluationQueueRepository.updateByPrimaryKeySelective(tEvaluationQueue);

				//去对应表里查要替换的模板数据
				//系统名称
				String evaluationtInformationId = tEvaluationQueue.getEvaluationtInformationId();
				String evaluationtInformationname = getEvaluationtInformationname(evaluationtInformationId);

				//文档名称
				String evaluationId = tEvaluationQueue.getEvaluationId();
				List<String[]> tableList = getEvaluationtMaterialName(evaluationId);

				//最后一行,是走替换
				String num = String.valueOf(tableList.size()+1);

				//往模板里放数据
				String outputUrl = makeOutputUrl();

				Map<String, String> testMap = new HashMap<String, String>();
				testMap.put("evaluationtInformationname", evaluationtInformationname);
				testMap.put("num", num);
				InputStream inStream = WorderToNewWordUtils.class.getClassLoader().getResourceAsStream("templates/用户资料使用登记表.docx");

				WorderToNewWordUtils.changWord(inStream,outputUrl,testMap,tableList);
				System.out.println("success");
				//走完这个循环,更改状态为2----结束
				tEvaluationQueue.setStatus(2);//只改动了status,只更新status
				tEvaluationQueueRepository.updateByPrimaryKeySelective(tEvaluationQueue);

				//还得往文件库里插入一条记录
				//调用插入文件的方法
				File file = new File(outputUrl);
				saveTfile(file,"6-1",evaluationId,"用户资料使用登记表.docx");
			}
		}
	}
	//serviceImpl层封装的方法
	//插入文件的方法----serviceImpl这个业务类方法中封装的拿数据的方法(getEntrustingAddress(evaluationId),getProjectName(evaluationId)),就不在罗列了,没什么实际作用
	//这个最后插入一条文件记录的方法,或许有点抛砖引玉的作用,暂且罗列一下
	public TFile saveTfile(File file,String evaluationTypeId,String evaluationId,String fileName){
		//文件信息保存
		TFile tFile = new TFile();
		tFile.setFileId(CommonUtils.getUUID());
		tFile.setEvaluationTypeId(evaluationTypeId);
		tFile.setDependId(evaluationId);
		tFile.setAttachmentPath(fileUploadPath);
		//文件上传名称
		String name = file.getName();//
		tFile.setAttachmentName(name);
		//原文件名----就是模板的名字
		tFile.setFileName(fileName);
		//文件后缀
		String prefix = file.getName().substring(file.getName().lastIndexOf("."));
		tFile.setFileType(prefix);
		tFile.setAttachmentSize(new Long(file.length()).floatValue());
		tFile.setState(StatusEnum.NORMAL.value());
		tFile.setCreateTime(ZonedDateTime.now());
		tFile.setCreateUser(SecurityUtils.getCurrentUserName());
		tFile.setUpdateTime(ZonedDateTime.now());
		tFile.setUpdateUser(SecurityUtils.getCurrentUserName());
		TFile insert = tFileService.insert(tFile);
		return insert;
	}
	//还有一个实现类方法中封装的一个有点扯淡的臭方法
	//文档名称
	List<String[]> getEvaluationtMaterialName(String evaluationId){
		//state=1  这里没有删除功能,可以不用考虑这个
		//这个考虑到属性的原因,还需要用t_evaluationt_material表里查evaluationt_material_name,直接连表查,返回map
		List<Map<String,String>> savedList = tEvaluationtDocumentsRepository.selectSaved(evaluationId);
		List<String[]> stringCells = new ArrayList<>();
		for (int i = 0; i < savedList.size(); i++) {

			Map<String, String> map = savedList.get(i);
			ArrayList<String> list = new ArrayList<>();//待会转成数组
			list.add(0,String.valueOf(i+1));
			if (map.size()<2){
				map.put("remark"," ");
				for (Map.Entry<String,String> entry : map.entrySet()){
					String key = entry.getKey();
					String value = entry.getValue();
					if ("evaluationtMaterialName".equals(key)){
						list.add(1,value);
					}
					if ("remark".equals(key)){
						list.add(2,value);
					}
				}
			}else {
				for (Map.Entry<String,String> entry : map.entrySet()){
					String key = entry.getKey();
					String value = entry.getValue();
					if ("remark".equals(key)){
						list.add(1,value);
					}
					if ("evaluationtMaterialName".equals(key)){
						list.add(2,value);
						String s = list.get(1);
						list.remove(s);
						list.add(s);
					}
				}
			}
			String[] stringcell = new String[]{list.get(0),list.get(1),list.get(2)};
			stringCells.add(stringcell);
		}
		return stringCells;
	}

此处用的工具类:

/**
 * 通过word模板生成新的word工具类
 */
public class WorderToNewWordUtils {

    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
    // * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     //* @param tableList 需要插入的表格信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(InputStream inStream,String outputUrl,
                                    Map<String, String> textMap,List<String[]> tableList) {

        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
//            InputStream inStream = null;
            //inStream = WorderToNewWordUtils.class.getClassLoader().getResourceAsStream("templates/网络安全等级保护测评报告评审表.docx");
            //POIXMLDocument.openPackage(inputUrl)
            XWPFDocument document = new XWPFDocument(inStream);
            //解析替换文本段落对象
            WorderToNewWordUtils.changeText(document, textMap);
            //解析替换表格对象
            WorderToNewWordUtils.changeTable(document, textMap,tableList);

            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            inStream.close();
            stream.close();

        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    //替换模板原来位置
                    String value = changeValue(run.toString(), textMap);
                    //run.setText(changeValue(run.toString(), textMap),0);
                    //分段显示的情况
                    String[] values = value.split("\n");
                    if(values.length > 1) {
                        run.setText(values[0],0);
                        for (int i = 1; i < values.length; i++) {
                            //存在分段则新建一个run
                            XWPFRun newrun = paragraph.insertNewRun(i);
                            //copy样式
                            newrun.getCTR().setRPr(run.getCTR().getRPr());
                            //换行
                            newrun.addBreak();
                            //缩进
                            //newrun.addTab();
                            newrun.setText(values[i]);
                        }
                        break;
                    }else {
                        run.setText(value,0);
                    }
                }
            }
        }

    }

    /**
     * 替换表格对象方法
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     //* @param tableList 需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap,List<String[]> tableList){
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
            //我的这里没有表头---------------//这是原来的注释:只处理 行数 大于等于2的 表格,且不循环表头
            XWPFTable table = tables.get(i);
            //if(table.getRows().size()>1){
            if(table.getRows().size()>0){
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if(checkText(table.getText())){
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);//我的这里不需要插入
                }else{
                    System.out.println("插入"+table.getText());
                    if (tableList!=null&&tableList.size()>0){
                        insertTable(table, tableList);
                    }
                }
            }
        }
    }



    /**
     * 遍历表格
     * @param rows 表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                if(checkText(cell.getText())){
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            String value  = changeValue(run.toString(), textMap);
                            //run.setText(value,0);
                            //分段显示的情况
                            String[] values = value.split("\n");
                            if(values.length > 1) {
                                run.setText(values[0],0);
                                for (int i = 1; i < values.length; i++) {
                                    //存在分段则新建一个run
                                    XWPFRun newrun = paragraph.insertNewRun(i);
                                    //copy样式
                                    newrun.getCTR().setRPr(run.getCTR().getRPr());
                                    //换行
                                    newrun.addBreak();
                                    //缩进
                                    //newrun.addTab();
                                    newrun.setText(values[i]);
                                }
                                break;
                            }else {
                                run.setText(value,0);
                            }

                        }
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     * @param table 需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<String[]> tableList){
        //创建行,根据需要插入的数据添加新行,不处理表头
        for(int i = 1; i <= tableList.size(); i++){
            XWPFTableRow row =table.createRow();
        }
        //遍历表格插入数据
        List<XWPFTableRow> rows = table.getRows();
        for(int i = 1; i < rows.size(); i++){
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for(int j = 0; j < cells.size(); j++){
                XWPFTableCell cell = cells.get(j);
                cell.setText(tableList.get(i-1)[j]);
            }
        }
    }
    /**
     * 判断文本中时候包含$
     * @param text 文本
     * @return 包含返回true,不包含返回false
     */
    public static boolean checkText(String text){
        boolean check  =  false;
        if(text.indexOf("$")!= -1){//这个段落里检索到了$
            check = true;//走if()去替换
        }
        return check;//不走if(),无需替换
    }
    /**
     * 匹配传入信息集合与模板
     * @param value 模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap){
        Set<Map.Entry<String, String>> textSets = textMap.entrySet();
        for (Map.Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${"+textSet.getKey()+"}";
            if(value.indexOf(key)!= -1){//模板需要替换的区域中检索到了
                value = textSet.getValue();//替换成传入信息集合中的value
            }
        }
        //模板未匹配到区域替换为空
        if(checkText(value)){
            value = "";
        }
        return value;
    }

}

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
使用POI操作Word可以实现动态添加行和表格中动态行,同时也支持插入图片。这里提供一个简单的示例代码: ``` import java.io.*; import org.apache.poi.xwpf.usermodel.*; public class WordUtils { private XWPFDocument document; public WordUtils() { document = new XWPFDocument(); } public void addParagraph(String text) { XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(text); } public void addTable(int rows, int cols) { XWPFTable table = document.createTable(rows, cols); for (int i = 0; i < rows; i++) { XWPFTableRow row = table.getRow(i); for (int j = 0; j < cols; j++) { XWPFTableCell cell = row.getCell(j); cell.setText(String.format("row %d, col %d", i, j)); } } } public void addDynamicTable(int rows, int cols, String[][] data) { XWPFTable table = document.createTable(rows, cols); for (int i = 0; i < rows; i++) { XWPFTableRow row = table.getRow(i); for (int j = 0; j < cols; j++) { XWPFTableCell cell = row.getCell(j); if (data[i][j].startsWith("<img")) { try { String fileName = data[i][j].substring(data[i][j].indexOf("src=") + 5, data[i][j].indexOf(">") - 1); FileInputStream fis = new FileInputStream(fileName); cell.removeParagraph(0); XWPFParagraph paragraph = cell.addParagraph(); XWPFRun run = paragraph.createRun(); run.addPicture(fis, Document.PICTURE_TYPE_JPEG, fileName, Units.toEMU(100), Units.toEMU(100)); fis.close(); } catch (Exception e) { e.printStackTrace(); } } else { cell.setText(data[i][j]); } } } } public void save(String fileName) { try { FileOutputStream fos = new FileOutputStream(fileName); document.write(fos); fos.close(); document.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 这个类中提供了三个方法分别用于添加段落、表格和动态表格。其中动态表格需要传入一个二维数组来表示表格中的数据,如果数据是以`<img>`开头的字符串,则表示该单元格需要插入一张图片图片的文件名应该在`src=`和`>`之间。最后调用`save`方法将文档保存到指定的文件中即可。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值