对于无法在浏览器中直接预览的文字文档(Word)、演示文档(PPT)和表格文档(Excel),您可以借助 WebOffice 的在线预览功能,实现直接在浏览器中查看文档内容,而无需下载文档。
使用场景
企业知识库或文档管理系统:员工可将文件上传并转化为网页格式,方便快速查看,提升信息访问效率和安全性。
在线教育平台:教师和学生可以实时查看教材、讲义和作业,促进互动和学习体验。
协同办公与项目管理工具:团队成员共享的工作计划、设计稿和报告文档可直接在浏览器中查看,提升团队协作效率。
支持的文件类型
文件类型 | 文件后缀 |
Word | doc、dot、wps、wpt、docx、dotx、docm、dotm、rtf |
PPT | ppt、pptx、pptm、ppsx、ppsm、pps、potx、potm、dpt、dps |
Excel | xls、xlt、et、xlsx、xltx、csv、xlsm、xltm |
注意事项
不建议对 OSS 文件执行跨境访问操作。例如,文件存储在新加坡地域的 Bucket 中,却从中国内地发起预览、读取或下载请求。在此类场景下,网络链路质量受跨境网络环境影响较大,可能出现访问延迟升高、预览失败、下载中断或连接不稳定等情况,因此无法保证网络稳定性和访问体验。建议尽量确保访问端与 Bucket 所在地域保持一致,避免跨境访问带来的不确定性。
WebOffice在线预览仅支持同步处理(x-oss-process处理方式)。
WebOffice 在线预览需通过后端服务调用 OSS SDK 生成签名 URL,不支持在前端代码中直接初始化 OSS SDK,也不支持直接通过 GET 参数形式构造预览 URL。
ali-ossSDK 需要传入accessKeyId和accessKeySecret参数,前端环境下可通过浏览器DevTools查看并窃取凭证,存在凭证泄露风险。以未签名的 GET 请求直接访问 OSS 对象会被拒绝(返回 403AccessDenied),签名机制确保访问合法性,避免未授权访问产生不可控的数据处理费用。后端生成的签名 URL 可在浏览器中直接使用,签名 URL 包含OSSAccessKeyId、Expires、Signature参数,有过期时间,过期后自动失效。
如何使用
前提条件
在OSS中创建存储空间(Bucket),上传需要预览的Office文档至Bucket中,并为该Bucket绑定智能媒体管理(IMM)的 Project,IMM Project需要跟Bucket在同一地域下。
需要您通过自定义域名访问OSS,通过自定义域名访问文件时才能打开预览。
说明如提示域名未配置至小程序的WebView白名单,请通过钉钉用户群(钉钉群号:88490020073)联系智能媒体管理技术支持。技术支持人员将根据用户提供的微信可信域名验证文件进行白名单配置。
获取URL链接实现预览
Java
要求使用3.17.4及以上版本的Java SDK,Java SDK的安装请参见安装。
package com.aliyun.oss.demo;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import java.net.URL;
import java.util.Date;
public class Demo {
public static void main(String[] args) throws Throwable {
// 请填写您的自定义域名。例如http://static.example.com。
String endpoint = "http://static.example.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径。如果不在Bucket根目录,需携带Object完整路径
String objectName = "exampledir/exampleobject.docx";
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
String region = "cn-hangzhou";
// 创建OSSClient实例。
// 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// 请注意,设置true开启CNAME选项。
clientBuilderConfiguration.setSupportCname(true);
// 显式声明使用 V4 签名算法
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 文档处理参数
String style = "doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60";
// 指定签名URL过期时间为3600秒)
Date expiration = new Date(new Date().getTime() + 3600 * 1000L );
GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
req.setExpiration(expiration);
req.setProcess(style);
URL signedUrl = ossClient.generatePresignedUrl(req);
System.out.println(signedUrl);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Python
要求使用Python SDK 2.18.4及以上版本,Python SDK的安装请参见安装(Python SDK V1)。
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# 填写Bucket名称
bucket = 'examplebucket'
# 请填写您的自定义域名。例如https://static.example.com。
endpoint = 'https://static.example.com'
# 填写阿里云通用Region ID
region = 'cn-hangzhou'
# 使用自定义域名初始化bucket
bucket = oss2.Bucket(auth, endpoint, bucket, is_cname=True, region=region)
# 指定处理文件
key = 'example.docx'
# 指定过期时间,单位秒
expire_time = 3600
# 构建在线预览的处理指令。
image_process = 'doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60'
# 生成签名URL,带上处理参数
url = bucket.sign_url('GET', key, expire_time, params={'x-oss-process': image_process}, slash_safe=True)
# 打印签名URL
print(url)Go
要求使用Go SDK 3.0.2及以上版本,Go SDK的安装请参见安装OSS Go SDK。
package main
import (
"context"
"flag"
"log"
"time"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定义全局变量
var (
region string // 存储区域
bucketName string // 存储空间名称
objectName string // 对象名称
)
// init函数用于初始化命令行参数
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
// 解析命令行参数
flag.Parse()
// 检查bucket名称是否为空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 检查region是否为空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 检查object名称是否为空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, object name required")
}
// 加载默认配置并设置凭证提供者和区域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region).
// 请填写您的自定义域名。例如http://static.example.com。
WithEndpoint("http://static.example.com").
WithUseCName(true)
// 创建OSS客户端
client := oss.NewClient(cfg)
// 生成GetObject的预签名URL
result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName),
// 设置文档处理参数
Process: oss.Ptr("doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60"),
}, oss.PresignExpires(10*time.Minute))
if err != nil {
log.Fatalf("failed to get object presign %v", err)
}
log.Printf("request method:%v\n", result.Method)
log.Printf("request expiration:%v\n", result.Expiration)
log.Printf("request url:%v\n", result.URL)
if len(result.SignedHeaders) > 0 {
// 当返回结果包含签名头时,使用签名URL发送GET请求时也包含相应的请求头,以免出现不一致,导致请求失败和签名错误
log.Printf("signed headers:\n")
for k, v := range result.SignedHeaders {
log.Printf("%v: %v\n", k, v)
}
}
}Node.js
要求使用Node.js SDK 8.0及以上版本,Node.js SDK的安装请参见安装(Node.js SDK)。
const OSS = require("ali-oss");
// 定义一个生成签名 URL 的函数
async function generateSignatureUrl(fileName) {
// 获取签名URL
const client = await new OSS({
// 请填写您的自定义域名。例如http://static.example.com。
endpoint: 'http://static.example.com',
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
bucket: 'examplebucket',
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: 'oss-cn-hangzhou',
authorizationV4: true,
cname: true
});
// 生成签名URL,并包含文档处理参数
return await client.signatureUrlV4('GET', 3600, {
headers: {}, // 请根据实际发送的请求头设置此处的请求头
queries: {
"x-oss-process": "doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60" // 添加文档处理参数
}
}, fileName);
}
// 调用函数并传入文件名
generateSignatureUrl('yourFileName').then(url => {
console.log('Generated Signature URL:', url);
}).catch(err => {
console.error('Error generating signature URL:', err);
});
PHP
要求使用PHP SDK 2.7.0及以上版本,PHP SDK的安装请参见安装(PHP SDK V1)。
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
//请填写您的自定义域名。例如http://static.example.com。
$endpoint = "http://static.example.com";
// 填写Bucket名称,例如examplebucket。
$bucket= "examplebucket";
// 如果文档位于Bucket根目录,则直接填写文档名称。如果文档不在Bucket根目录,需携带文档完整路径,例如exampledir/example.docx。
$object = 'example.docx';
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"cname" => true,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
// 生成一个带处理参数的签名的URL,有效期是3600秒,可以直接使用浏览器访问。
$timeout = 3600;
$options = array(
// 构建在线预览的处理指令。
OssClient::OSS_PROCESS => "doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60");
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET", $options);
print("url: \n" . $signedUrl);生成的签名URL示例如下:
http://static.example.com/example.docx?x-oss-process=doc%2Fpreview%2Cexport_1%2Cprint_1%2Fwatermark%2Ctext_5YaF6YOo6LWE5paZ%2Csize_30%2Ct_60&x-oss-date=20250122T020741Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI********************%2F20250122%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=514ed93accdb80921c4b2897c6147fdb1599308c6457f68ee0ac2f771c7d0312复制生成的URL并粘贴到浏览器地址栏,按回车键即可预览WebOffice文档。
参数说明
操作名称:doc/preview
具体参数如下表所示:
参数名称 | 类型 | 是否必须 | 描述 |
int | 否 | 是否允许打印。取值:
| |
copy | int | 否 | 是否允许复制。取值:
|
export | int | 否 | 是否允许导出为PDF。取值:
|
maxpage | int | 否 | 最大渲染页数,取大于0的整数。 |
watermark | string | 否 | 水印参数。 |
text | string | 否 | 水印文字,需经过URL Safe的Base64编码。具体操作,请参见水印编码,推荐通过base64url encoder进行编码。 父节点:watermark |
size | int | 否 | 水印文字字号,取大于0的整数。 父节点:watermark |
t | int | 否 | 水印文字透明度。取值范围:0~100。默认值:100(不透明)。 父节点:watermark |
color | string | 否 | 水印文字颜色,RGB颜色值,默认值为#FFFFFF。 例如:#000000表示黑色,#FFFFFF表示白色。 父节点:watermark |
rotate | int | 否 | 指定文字顺时针旋转角度。取值范围:0~360。默认值为0(不旋转)。 父节点:watermark |
type | string | 否 | 指定文字水印的字体,需经过URL Safe的Base64编码。具体操作,请参见水印编码,推荐通过base64url encoder进行编码。 支持的字体如下:
父节点:watermark |
相关API
以上操作方式底层基于API实现,如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。关于公共请求头Authorization的计算方法,请参见签名版本4(推荐)。
预览信息
预览文档名称:example.docx
预览页面:文档前3页
预览页面水印信息:
水印类型:文字水印
水印文字:内部资料
水印字号:30号字体
水印透明度:60
预览页面权限信息:允许用户复制、导出、打印
处理示例
GET /example.docx?x-oss-process=doc/preview,export_1,print_1/watermark,text_5YaF6YOo6LWE5paZ,size_30,t_60 HTTP/1.1
Host: doc-demo.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 28 Oct 2022 06:40:10 GMT
Authorization: SignatureValue权限说明
阿里云账号默认拥有全部权限。阿里云账号下的RAM用户或RAM角色默认没有任何权限,需要阿里云账号或账号管理员通过RAM Policy概述或Bucket Policy授予操作权限。
API | Action | 说明 |
GetObject |
| 下载Object。 |
| 下载Object时,如果通过versionId指定了Object的版本,则需要授予此操作的权限。 | |
| 下载Object时,如果Object的元数据包含X-Oss-Server-Side-Encryption: KMS,则需要此操作的权限。 |
API | Action | 说明 |
无 |
| 通过OSS使用IMM进行数据处理的权限。 |
API | Action | 说明 |
GenerateWebofficeToken |
| 用于获取Weboffice凭证。 |
RefreshWebofficeToken |
| 用于刷新Weboffice凭证。 |
计费说明
WebOffice在线预览功能会产生以下计费项。有关计费项的定价详情,请参见OSS产品定价和计费项。
API | 计费项 | 说明 |
GetObject | GET 类型请求 | 根据成功的请求次数计算请求费用。 |
外网流出流量费用 | 如果是通过外网Endpoint(示例值oss-cn-hangzhou.aliyuncs.com)或者传输加速Endpoint(示例值oss-accelerate.aliyuncs.com)调用GetObject接口时,会产生外网流出流量费用,根据数据容量大小计费。 | |
低频访问数据取回容量 | 如果取回的数据是低频访问数据,会产生低频访问数据取回容量的费用,按数据取回量计费。 | |
归档直读数据取回容量 | 如果读取的是归档的Object且Bucket开启了归档直读,会产生归档直读数据取回容量费用,根据取回的数据容量大小计费。 | |
传输加速 | 如果开启了传输加速功能且使用传输加速域名访问您的Bucket会产生传输加速费用,根据数据容量大小计费。 |
API | 计费项 | 说明 |
GenerateWebofficeToken | DocumentWebofficePreview | 文档预览功能会产生文档处理费用。 重要 截至2023年12月1日之前创建的在线预览项目将根据文档的打开次数进行收费,而2023年12月1日及之后创建的项目则将按照API接口的调用次数计费。 |
RefreshWebofficeToken |
常见问题
是否支持预览动态PPT中的动画和视频?
支持预览动态PPT中的动画和视频,但请注意,在线预览功能最大支持200 MB的文档,超过200 MB则无法访问。
是否支持预览图片文件?
不支持。图片文件(如 jpg、png、gif 等)不通过 WebOffice 预览,但可直接通过文件 URL 在浏览器中预览,无需调用文档在线预览 SDK。若图片被强制下载,请检查 Content-Disposition 和 Content-Type 设置。详情请参见如何配置访问 OSS 文件时的预览行为?。
开启CDN后生成带签名的文档URL报错Either the Signature query string parameter or the Authorization header should be specified, not both.
如果您在私有 Bucket 开启回源功能后,通过 CDN 域名访问已绑定至 IMM 项目的 Bucket 中的文件,无需提供额外的签名信息。请按照以下要求进行配置:
授权默认角色 您需要为CDN的默认角色
AliyunCDNAccessingPrivateOSSRole授予oss:ProcessImm、imm:GenerateWebofficeToken以及imm:RefreshWebofficeToken的权限。访问资源时,应使用不包含签名信息的 URL。
例如,您可以使用如下格式的URL:http://cdn.example.info/demo.ppt?x-oss-process=doc/preview,export_1,print_1 使用文档在线预览功能。
为什么使用 xlsx 文件预览时变成下载?
使用 x-oss-process 参数进行文档在线预览时,如果使用了 pdf/preview、xls/preview、xlsx/preview 等格式特定参数,OSS 会将其视为无效参数,直接返回原始文件并附带 Content-Disposition: attachment 头,导致浏览器下载文件而非在线预览。
正确做法:统一使用 doc/preview 参数进行文档预览:
x-oss-process=doc/preview,export_1,print_1/watermark,text_<水印内容>,size_30,t_60使用前请确保已开通 IMM 智能媒体管理服务并完成 Bucket 绑定。