本文介紹了Java ApachePOI:在文本前面插入圖像的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我的docx文件中有一個占位符圖像,我想用新圖像替換它。問題是–占位符圖像在文本前面有一個屬性,而新圖像沒有。因此,對齊方式會中斷。下面是我的代碼片段以及帶有占位符的docx和結果docx。
.......
replaceImage(doc, "Рисунок 1", qr, 50, 50);
ByteArrayOutputStream out = new ByteArrayOutputStream();
doc.write(out);
out.close();
return out.toByteArray();
}
}
public XWPFDocument replaceImage(XWPFDocument document, String imageOldName, byte[] newImage, int newImageWidth, int newImageHeight) throws Exception {
try {
int imageParagraphPos = -1;
XWPFParagraph imageParagraph = null;
List<IBodyElement> documentElements = document.getBodyElements();
for (IBodyElement documentElement : documentElements) {
imageParagraphPos++;
if (documentElement instanceof XWPFParagraph) {
imageParagraph = (XWPFParagraph) documentElement;
if (imageParagraph.getCTP() != null && imageParagraph.getCTP().toString().trim().contains(imageOldName)) {
break;
}
}
}
if (imageParagraph == null) {
throw new Exception("Unable to replace image data due to the exception:
"
+ "'" + imageOldName + "' not found in in document.");
}
ParagraphAlignment oldImageAlignment = imageParagraph.getAlignment();
// remove old image
boolean isDeleted = document.removeBodyElement(imageParagraphPos);
// now add new image
XWPFParagraph newImageParagraph = document.createParagraph();
XWPFRun newImageRun = newImageParagraph.createRun();
newImageParagraph.setAlignment(oldImageAlignment);
try (InputStream is = new ByteArrayInputStream(newImage)) {
newImageRun.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, "qr",
Units.toEMU(newImageWidth), Units.toEMU(newImageHeight));
}
// set new image at the old image position
document.setParagraph(newImageParagraph, imageParagraphPos);
// NOW REMOVE REDUNDANT IMAGE FORM THE END OF DOCUMENT
document.removeBodyElement(document.getBodyElements().size() - 1);
return document;
} catch (Exception e) {
throw new Exception("Unable to replace image '" + imageOldName + "' due to the exception:
" + e);
}
}
帶占位符的圖像:
enter image description here
生成的圖像:
enter image description here
推薦答案
若要替換Microsoft Word中的圖片模板,無需將其刪除。
存儲是這樣的:
嵌入的媒體以二進制文件的形式存儲。這是圖片數據(XWPFPictureData
)。在文檔中,圖片元素(XWPFPicture
)鏈接到該圖片數據。
XWPFPicture
具有位置、大小和文本流動設置。不需要更改這些設置。
需要在XWPFPictureData
中更改。在那里,用戶可以用新的二進制內容替換舊的二進制內容。
因此,需要在文檔中找到XWPFPicture
。在文檔中插入圖片時存儲了一個非視覺圖片名稱。因此,如果一個人知道這個名字,那么這可能是找到這張照片的標準。
如果找到,則可以從找到的XWPFPicture
獲得XWPFPictureData
。有方法XWPFPicture.getPictureData
可以這樣做。然后,可以用新的二進制內容替換舊的二進制內容XWPFPictureData
。XWPFPictureData
是一個包部件。因此它必須PackagePart.getOutputStream
獲取要寫入的輸出流。
下面的完整示例顯示了全部。
source.docx
需要具有名為&qot;QRTemplate.jpg";的嵌入圖片。這是使用Word圖形用戶界面將圖片插入Word文檔時使用的源文件的名稱。并且需要包含新內容的文件QR.jpg
。
然后result.docx
將名為";QRTemplate.jpg";的所有圖片替換為給定文件QR.jpg
的內容。
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
public class WordReplacePictureData {
static XWPFPicture getPictureByName(XWPFRun run, String pictureName) {
if (pictureName == null) return null;
for (XWPFPicture picture : run.getEmbeddedPictures()) {
String nonVisualPictureName = picture.getCTPicture().getNvPicPr().getCNvPr().getName();
if (pictureName.equals(nonVisualPictureName)) {
return picture;
}
}
return null;
}
static void replacePictureData(XWPFPictureData source, String pictureResultPath) {
try ( FileInputStream in = new FileInputStream(pictureResultPath);
OutputStream out = source.getPackagePart().getOutputStream();
) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
static void replacePicture(XWPFRun run, String pictureName, String pictureResultPath) {
XWPFPicture picture = getPictureByName(run, pictureName);
if (picture != null) {
XWPFPictureData source = picture.getPictureData();
replacePictureData(source, pictureResultPath);
}
}
public static void main(String[] args) throws Exception {
String templatePath = "./source.docx";
String resultPath = "./result.docx";
String pictureTemplateName = "QRTemplate.jpg";
String pictureResultPath = "./QR.jpg";
try ( XWPFDocument document = new XWPFDocument(new FileInputStream(templatePath));
FileOutputStream out = new FileOutputStream(resultPath);
) {
for (IBodyElement bodyElement : document.getBodyElements()) {
if (bodyElement instanceof XWPFParagraph) {
XWPFParagraph paragraph = (XWPFParagraph)bodyElement;
for (XWPFRun run : paragraph.getRuns()) {
replacePicture(run, pictureTemplateName, pictureResultPath);
}
}
}
document.write(out);
}
}
}
這篇關于Java ApachePOI:在文本前面插入圖像的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,