参考资料:
搭建参考:https://zhuanlan.zhihu.com/p/357370263
编辑实现:https://blog.csdn.net/CSDN877425287/article/details/118256620
官方参考:https://learn.microsoft.com/zh-cn/officeonlineserver/deploy-office-online-server
编辑注意:https://blog.csdn.net/zxl782340680/article/details/88125732
注意事项:
1、不要再域控服务器上部署oos,会导致文档无法加载。
2、不要再oos服务上部署服务,这玩意好资源。
3、其他参看文档就够了。
补充,由于oos的域名机制,我们可以自定义代理服务器,这里使用springcloudgateway实现:
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway</artifactId>
<version>3.1.3</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
spring:
cloud:
gateway:
routes:
- id: fileserver
predicates:
- Path=/inner/api/**
uri: http://localhost/inner/api
- id: modifyresponse
predicates:
- Path=/**
uri: http://172.16.0.97:5081
package com.yak.gateway.filter;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
/**
* @author niemingming
* @Date 2022/9/28
*/
@Component
public class CustomResponseFilter implements GlobalFilter, Ordered {
private String source = "oos.gogetter.cn";
private String target = "172.16.0.97:5080";
private String source1 = "oos.gogetter.cn:80";
private String target1 = "172.16.0.97:5080";
private String source2 = "\\u00253A\\u00252F\\u00252Foos\\u00252Egogetter\\u00252Ecn";
private String target2 = "\\u00253A\\u00252F\\u00252Flocalhost\\u00253A9003";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("进入路由:" + exchange.getRequest().getURI());
if (exchange.getRequest().getURI().getPath().contains("/inner/api/oos")) {
// 文件服务不做处理
return chain.filter(exchange);
}
ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (this.getDelegate().getHeaders().getContentType() != null
&& this.getDelegate().getHeaders().getContentType().toString().contains("text/html")) {
// html需要获取内容,并重写
Flux<? extends DataBuffer> flux = Flux.from(body).map(b -> {
try(ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream in = b.asInputStream()) {
byte[] buff = new byte[1024];
int len = 0;
while ((len = in.read(buff)) > 0) {
bos.write(buff, 0, len);
}
// 释放内存
DataBufferUtils.release(b);
String content = new String(bos.toByteArray(), StandardCharsets.UTF_8);
content = content.replace(source1, target1).replace(source, target); // .replace(source2, target2)
return this.getDelegate().bufferFactory().wrap(content.getBytes(StandardCharsets.UTF_8));
}catch (Exception e){
e.printStackTrace();
}
return b;
});
return super.writeWith(flux);
}
// 去掉头部水印
String wordsource = "this.$EN.id=\"ExternalHeaderViewerChromeTopBars\",this.$Ji.appendChild(this.$EN)";
String wordtarget = "his.$EN.id=\"ExternalHeaderViewerChromeTopBars\"";
// WordViewer.js 隐藏word标题行
if (exchange.getRequest().getURI().getPath().contains("WordViewer.js")) {
// word处理
Flux<? extends DataBuffer> flux = replaceData(body, wordsource, wordtarget);
return super.writeWith(flux);
}
// excel Ewa.cuixas.js
String excelsource = "this.f.id=\"ExternalHeaderViewerChromeTopBars\",this.j.appendChild(this.f)";
String exceltarget = "this.f.id=\"ExternalHeaderViewerChromeTopBars\"";
if (exchange.getRequest().getURI().getPath().contains("Ewa.cuixas.js")) {
// word处理
Flux<? extends DataBuffer> flux = replaceData(body, excelsource, exceltarget);
return super.writeWith(flux);
}
// ppt bootView.js this.$FL.id = "ExternalHeaderViewerChromeTopBars",
// this.$LP.appendChild(this.$FL),
String pptsource = "this.$FL.id=\"ExternalHeaderViewerChromeTopBars\",this.$LP.appendChild(this.$FL)";
String ppttarget = "this.$FL.id=\"ExternalHeaderViewerChromeTopBars\"";
if (exchange.getRequest().getURI().getPath().contains("bootView.js")) {
// word处理
Flux<? extends DataBuffer> flux = replaceData(body, pptsource, ppttarget);
return super.writeWith(flux);
}
System.out.println("其他路由:" + exchange.getRequest().getURI());
return super.writeWith(body);
}
private Flux<? extends DataBuffer> replaceData(Publisher<? extends DataBuffer> body, String wordsource, String wordtarget) {
return Flux.from(body).map(b -> {
try(ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream in = b.asInputStream()) {
byte[] buff = new byte[1024];
int len = 0;
while ((len = in.read(buff)) > 0) {
bos.write(buff, 0, len);
}
// 释放内存
DataBufferUtils.release(b);
String content = new String(bos.toByteArray(), StandardCharsets.UTF_8);
content = content.replace(wordsource, wordtarget); // .replace(source2, target2)
return this.getDelegate().bufferFactory().wrap(content.getBytes(StandardCharsets.UTF_8));
}catch (Exception e){
e.printStackTrace();
}
System.out.println("2222");
return b;
});
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
System.out.println(222222222);
return this.writeWith(Flux.from(body).flatMapSequential((p) -> {
return p;
}));
}
};
return chain.filter(exchange.mutate().response(responseDecorator).build());
}
@Override
public int getOrder() {
return -1;
}
}