为有中文需求的客户提供多渠道中文技术支持.

Thu Jul 01, 2021 9:40 am

截图.jpg
截图.jpg
前端通过MultipartFile上传了文件,如docx,在服务器端增加了水印以后,我现在希望通过document.saveToStream,将处理过的文件写入到outputStream中,然后将outputStream转成inputStream,转换的目的是因为加入水印该功能是为了嵌入到一个旧的系统中,原逻辑是直接将MultipartFile写入到文件系统,所以希望outputStream转成inputStream,再用inputStream构造新的MultipartFile然后继续后续处理逻辑,如下是代码,但是outputStream要报空指针错误,如何初始化才能确保加入的水印不受影响及,并能支持outputstream能生成有效的MultipartFile

Document document = new Document();
document.loadFromStream(file.getInputStream(), FileFormat.Docx);
// 写入水印
insertTextWatermark(document.getSections().get(0), account);

outputpath = directory.getCanonicalPath() + "/src/test/java/output/" + wmfile;
File testfile = new File(outputpath);

// 这里outputStream要报空指针错误,如何初始化才能确保加入的水印不受影响?
document.saveToStream(outputStream, FileFormat.Docx);

// 从输出流转换到输入流
inputStream = scu.parse(outputStream);

file = getMultipartFile(inputStream, fileName);

return file;

xkdzy2002
 
Posts: 3
Joined: Wed Jun 23, 2021 4:16 pm

Thu Jul 01, 2021 11:22 am

您好,

感谢您的咨询。
对于您提到的空指针异常,我模拟了一个Word文档,使用如下代码进行了测试,但并没有遇到任何问题。为了帮助我们进一步调查,请提供您的测试文档和完整的测试代码。
另外,关于将outputstream转换为MultiPartFile,抱歉这个不是我们产品的范畴。建议您可以在网上搜索一下解决方案。

Code: Select all
    public static void main(String[] args) throws FileNotFoundException {
        File file=new File("测试.docx");
        Document document = new Document();
        document.loadFromStream(new FileInputStream(file),FileFormat.Docx);
        addWatermark(document);

        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        document.saveToStream(outputStream, FileFormat.Docx);
    }

    private static void addWatermark(Document document) {
        PictureWatermark picture = new PictureWatermark();
        picture.setPicture("logo.png");
        picture.setScaling(250);
        picture.isWashout(false);
        document.setWatermark(picture);
    }
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Thu Jul 01, 2021 3:16 pm

:D :D :D 好使了, outputStream=new ByteArrayOutputStream();


// 从前端传入的MultipartFile加水印后返回新的MultipartFile用于后续业务逻辑处理

public MultipartFile DocWaterMark(MultipartFile file, String account, String suffix) {
File directory = new File(".");
final String originalFileName = file.getOriginalFilename();
String fileName = originalFileName;
String[] fileSplits = null;
String datapath = "", outputpath = "";
String wmfile = "test.docx";

Date date = new Date();
String dateStr = dateFormat.format(date);
OutputStream outputStream = null;
InputStream inputStream = null;
try {

Document document = new Document();
document.loadFromStream(file.getInputStream(), FileFormat.Docx);
// 写入水印
insertTextWatermark(document.getSections().get(0), account);

outputpath = directory.getCanonicalPath() + "/src/test/java/output/" + wmfile;
File testfile = new File(outputpath);

outputStream=new ByteArrayOutputStream();
document.saveToStream(outputStream, FileFormat.Docx);

// 从输出流转换到输入流,scu为将outputStream和inputStream互转的工具类StreamConvertUtil
inputStream = scu.parse(outputStream);

file = getMultipartFile(inputStream, fileName);

// 写入指定的目录用于测试
file.transferTo(testfile);
// 返回到业务逻辑调用用于后续处理
return file;

} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("文件名:" + fileName + " 文件类型:" + file.getContentType() + " 文件大小:" + file.getSize() + "增加 " + suffix + "水印 " + " 责任人:" + account + " 时间:" + dateStr);
return null;
}

@Component
public class StreamConvertUtil {

//inputStream转outputStream
public ByteArrayOutputStream parse(InputStream in) throws Exception {
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
int ch;
while ((ch = in.read()) != -1) {
swapStream.write(ch);
}
return swapStream;
}

//outputStream转inputStream
public ByteArrayInputStream parse(OutputStream out) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream;
}

//inputStream转String
public String parse_String(InputStream in) throws Exception {
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
int ch;
while ((ch = in.read()) != -1) {
swapStream.write(ch);
}
return swapStream.toString();
}

//OutputStream 转String
public String parse_String(OutputStream out) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream.toString();
}

//String转inputStream
public ByteArrayInputStream parse_inputStream(String in) throws Exception {
ByteArrayInputStream input = new ByteArrayInputStream(in.getBytes());
return input;
}

//String 转outputStream
public ByteArrayOutputStream parse_outputStream(String in) throws Exception {
return parse(parse_inputStream(in));
}
}

/**
* 获取封装得MultipartFile
*
* @param inputStream inputStream
* @param fileName fileName
* @return MultipartFile
*/
public MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
FileItem fileItem = createFileItem(inputStream, fileName);
//CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
return new CommonsMultipartFile(fileItem);
}

/**
* FileItem类对象创建
*
* @param inputStream inputStream
* @param fileName fileName
* @return FileItem
*/
public FileItem createFileItem(InputStream inputStream, String fileName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "file";
FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
OutputStream os = null;
//使用输出流输出输入流的字节
try {
os = item.getOutputStream();
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
inputStream.close();
} catch (IOException e) {
logger.error("Stream copy exception", e);
throw new IllegalArgumentException("文件上传失败");
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
logger.error("Stream close exception", e);

}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.error("Stream close exception", e);
}
}
}

return item;
}
}

xkdzy2002
 
Posts: 3
Joined: Wed Jun 23, 2021 4:16 pm

Fri Jul 02, 2021 9:49 am

您好,

感谢您的回复。
从您的回复来看,您的问题已经被解决了,对吗?
同时我也基于您提供的代码,进行了一些修改后做了初步测试,并没有遇到空指针异常。如果还有任何有关我们产品的问题,还请您提供您的可运行项目帮助我们进一步调查。
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Return to 中文技术支持