Compare commits

...

35 Commits
v1.1 ... v2.0

Author SHA1 Message Date
陈精华
3813f75f65 2.0版本 2019-05-07 10:16:26 +08:00
陈精华
a663e99bcd 背景色统一 2019-04-28 13:55:40 +08:00
陈精华
d517ab4e6f 替换pdf和图片预览相互转跳按钮图标 2019-04-28 13:55:40 +08:00
陈精华
29726c11a3 PDF预览也支持图片模式和查看大图 2019-04-28 13:55:40 +08:00
陈精华
336a18ade7 office预览只有PDF转图片 2019-04-26 15:35:43 +08:00
陈精华
53814fe6ab office图片&PDF预览背景色统一 2019-04-26 14:54:09 +08:00
陈精华
50fb586e6f office图片预览打开大图新开窗口 2019-04-26 14:25:35 +08:00
陈精华
a49ee9d726 图片预览可在viewjs中大图预览&翻页 2019-04-26 14:15:08 +08:00
陈精华
ae40d0233b 加入shutdown脚本 2019-04-26 14:15:08 +08:00
陈精华
8f7c13850e 修复调试时只打开jodconverter-web目录里读不到配置文件异常 2019-04-26 14:15:08 +08:00
陈精华
b4d3419797 word、ppt文档新增图片预览模式 2019-04-26 09:04:34 +08:00
陈精华
68aa5db66b RocksDB缓存实现,并更换默认实现为RocksDB 2019-04-23 11:40:44 +08:00
陈精华
7e8de7c754 解压相关 2019-04-18 16:14:58 +08:00
陈精华
f989fbf9c9 优先使用自定义office.home 2019-04-18 11:53:59 +08:00
陈精华
af8ddc10da 文件转换编码默认根据操作系统获取,变为可选配置
文本和多媒体类型添加默认值,变为可选配置
2019-04-17 13:32:14 +08:00
陈精华
3713e6e550 MacOS下office安装路径更新 2019-04-17 13:32:14 +08:00
陈精华
4a7ba07df1 file.Dir变为选配置添加其默认值 2019-04-16 22:10:48 +08:00
陈精华
b625381de3 脚本修改 2019-04-16 16:11:22 +08:00
陈精华
0968ac774a 脚本修改 2019-04-16 16:11:22 +08:00
陈精华
0db6b23bf7 Linux下集成OpenOffice 2019-04-16 16:11:22 +08:00
陈精华
6dc10e8df4 解决tar包office目录层级过长问题 2019-04-16 16:11:22 +08:00
陈精华
9976f0ae99 dev和release区分开 2019-04-16 16:11:22 +08:00
陈精华
55537d3a25 Windows下集成OpenOffice 2019-04-16 16:11:22 +08:00
陈精华
02e116fd8a 完善启动脚本 2019-04-16 16:11:22 +08:00
陈精华
5af3a97720 支持部分配置在运行时动态改变 2019-04-16 16:11:22 +08:00
陈精华
bf08c2c26f 更新记录 2019-04-16 16:11:22 +08:00
陈精华
236ed405f2 启动脚本&配置文件 2019-04-16 16:11:22 +08:00
陈精华
0fb02e3ccb 打包为zip和tar.gz包 2019-04-16 16:11:22 +08:00
陈精华
3dd6609fd6 缓存及队列实现抽象,提供JDK和REDIS两种实现 2019-04-16 16:11:22 +08:00
kl
dd876792c7 Update pom.xml 2018-10-22 11:34:30 +08:00
kl
3b79ef31e8 Update pom.xml
更新jar版本依赖,老版本有安全风险
2018-10-17 09:09:02 +08:00
kl
deb3abcac1 Merge remote-tracking branch 'origin/master' 2018-03-26 17:06:42 +08:00
kl
1c1a945959 使用畅言替换友言社评服务 2018-03-26 17:03:20 +08:00
duanmuxiangxiao
d1c5211d03 viewerjs版本升级release 1.0.0-rc.1 2018-03-26 16:48:02 +08:00
duanmuxiangxiao
d73bc3a031 图片轮播,修改图片切换按钮样式 2018-03-26 13:39:54 +08:00
3656 changed files with 673755 additions and 182 deletions

1
.gitignore vendored
View File

@@ -28,7 +28,6 @@ nbdist/
.classpath .classpath
.project .project
**/.settings **/.settings
**/bin/
**/build/ **/build/
**/.externalToolBuilders/ **/.externalToolBuilders/
*.iml *.iml

View File

@@ -57,15 +57,13 @@ Considering space issues, the pictures of other types of documents will not be s
- Redisson - Redisson
- Jodconverter - Jodconverter
> Dependencies > Dependencies
- Redis - Redis(Optional, Unnecessary by default)
- OpenOffice or LibreOffice - OpenOffice or LibreOffice
1. First step`git pull https://github.com/kekingcn/file-online-preview.git` 1. First step`git pull https://github.com/kekingcn/file-online-preview.git`
2. Second stepconfigure redis address and OpenOffice directorysuch as 2. Second stepconfigure redis address and OpenOffice directorysuch as
``` ```
#=============================================#Spring Redisson Configuration#===================================#
spring.redisson.address = 192.168.1.204:6379
##The folder for files which are uploaded to the server(Because of running as jar) ##The folder for files which are uploaded to the server(Because of running as jar)
file.dir = C:\\Users\\yudian\\Desktop\\dev\\ file.dir = C:\\Users\\yudian\\Desktop\\dev\\
## openoffice configuration ## openoffice configuration
@@ -80,6 +78,10 @@ If everything is ok,you will see the picture below.
### Changelog ### Changelog
> April 8th 2019
1. Cache and queue implementations abstract, providing JDK and REDIS implementations (REDIS becomes optional dependencies)
2. Provides zip and tar.gz packages, and provides a one-click startup script
> January 17th 2018 > January 17th 2018
1. Refined the project directory, abstract file preview interface, Easy to extend more file extensions and depoly this project on your own 1. Refined the project directory, abstract file preview interface, Easy to extend more file extensions and depoly this project on your own

View File

@@ -50,15 +50,13 @@ QQ群号613025121
- redisson - redisson
- jodconverter - jodconverter
> 依赖外部环境 > 依赖外部环境
- redis - redis (可选,默认不用)
- OpenOffice或者LibreOffice - OpenOffice或者LibreOffice
1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git 1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git
2. 第二步:配置redis地址和OpenOffice目录 2. 第二步配置OpenOffice目录
``` ```
#=============================================#spring Redisson配置#===================================#
spring.redisson.address = 192.168.1.204:6379
##资源映射路径(因为jar方式运行的原因) ##资源映射路径(因为jar方式运行的原因)
file.dir = C:\\Users\\yudian\\Desktop\\dev\\ file.dir = C:\\Users\\yudian\\Desktop\\dev\\
## openoffice相关配置 ## openoffice相关配置
@@ -73,6 +71,10 @@ file.dir为转换文件实际存储地址注意要以/结尾
### 历史更新记录 ### 历史更新记录
> 2019年04月08日
1. 缓存及队列实现抽象提供JDK和REDIS两种实现(REDIS成为可选依赖)
2. 打包方式提供zip和tar.gz包并提供一键启动脚本
> 2018年01月19日 > 2018年01月19日
1. 大文件入队提前处理 1. 大文件入队提前处理

View File

@@ -12,8 +12,11 @@
// //
package org.artofsolving.jodconverter.office; package org.artofsolving.jodconverter.office;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import org.artofsolving.jodconverter.util.PlatformUtils; import org.artofsolving.jodconverter.util.PlatformUtils;
@@ -61,29 +64,40 @@ public class OfficeUtils {
} }
public static File getDefaultOfficeHome() { public static File getDefaultOfficeHome() {
if (System.getProperty("office.home") != null) { Properties properties = new Properties();
return new File(System.getProperty("office.home")); String customizedConfigPath = getCustomizedConfigPath();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(customizedConfigPath));
properties.load(bufferedReader);
} catch (Exception e) {}
if (properties.getProperty("office.home") != null) {
return new File(properties.getProperty("office.home"));
} }
if (PlatformUtils.isWindows()) { if (PlatformUtils.isWindows()) {
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones // %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
String homePath = OfficeUtils.getHomePath();
String programFiles = System.getenv("ProgramFiles(x86)"); String programFiles = System.getenv("ProgramFiles(x86)");
if (programFiles == null) { if (programFiles == null) {
programFiles = System.getenv("ProgramFiles"); programFiles = System.getenv("ProgramFiles");
} }
return findOfficeHome( return findOfficeHome(
programFiles + File.separator + "OpenOffice 4", programFiles + File.separator + "OpenOffice 4",
programFiles + File.separator + "LibreOffice 4" programFiles + File.separator + "LibreOffice 4",
homePath + File.separator + "office"
); );
} else if (PlatformUtils.isMac()) { } else if (PlatformUtils.isMac()) {
return findOfficeHome( return findOfficeHome(
"/Applications/OpenOffice.org.app/Contents", "/Applications/OpenOffice.org.app/Contents",
"/Applications/OpenOffice.app/Contents",
"/Applications/LibreOffice.app/Contents" "/Applications/LibreOffice.app/Contents"
); );
} else { } else {
// Linux or other *nix variants // Linux or other *nix variants
return findOfficeHome( return findOfficeHome(
"/opt/openoffice.org3", "/opt/openoffice.org3",
"/opt/openoffice",
"/opt/libreoffice", "/opt/libreoffice",
"/opt/openoffice4",
"/usr/lib/openoffice", "/usr/lib/openoffice",
"/usr/lib/libreoffice" "/usr/lib/libreoffice"
); );
@@ -108,4 +122,29 @@ public class OfficeUtils {
} }
} }
public static String getHomePath() {
String userDir = System.getenv("KKFILEVIEW_BIN_FOLDER");
if (userDir == null) {
userDir = System.getProperty("user.dir");
}
if (userDir.endsWith("bin")) {
userDir = userDir.substring(0, userDir.length() - 4);
} else {
String separator = File.separator;
if (userDir.contains("jodconverter-web")) {
userDir = userDir + separator + "src" + separator + "main";
} else {
userDir = userDir + separator + "jodconverter-web" + separator + "src" + separator + "main";
}
}
return userDir;
}
public static String getCustomizedConfigPath() {
String homePath = OfficeUtils.getHomePath();
String separator = java.io.File.separator;
String configFilePath = homePath + separator + "conf" + separator + "application.properties";
return configFilePath;
}
} }

View File

@@ -10,7 +10,9 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>jodconverter-web</artifactId> <groupId>cn.keking</groupId>
<artifactId>kkFileView</artifactId>
<version>2.0</version>
<properties> <properties>
@@ -104,13 +106,13 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId> <artifactId>commons-compress</artifactId>
<version>1.9</version> <version>1.18</version>
</dependency> </dependency>
<!-- 解压(rar)--> <!-- 解压(rar)-->
<dependency> <dependency>
<groupId>com.github.junrar</groupId> <groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId> <artifactId>junrar</artifactId>
<version>0.7</version> <version>4.0.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.sourceforge.jchardet</groupId> <groupId>net.sourceforge.jchardet</groupId>
@@ -149,6 +151,26 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>19.0</version> <version>19.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>5.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.15</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.15</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<resources> <resources>
@@ -159,12 +181,36 @@
</includes> </includes>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
<resource>
<directory>src/main/conf</directory>
<excludes>
<exclude>${build.exclude.resource}</exclude>
</excludes>
</resource>
</resources> </resources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -0,0 +1,2 @@
#!/bin/bash
kill 15 `ps -ef|grep kkFileView|awk '{print $2}'`

View File

@@ -0,0 +1,7 @@
@echo off
set "KKFILEVIEW_BIN_FOLDER=%cd%"
cd "%KKFILEVIEW_BIN_FOLDER%"
echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER%
echo Starting kkFileView...
echo Please check log file for more information
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\conf\application.properties -jar kkFileView-2.0.jar -> ..\log\kkFileView.log

View File

@@ -0,0 +1,30 @@
#!/bin/bash
DIR_HOME=("/opt/openoffice.org3" "/opt/libreoffice" "/opt/openoffice4" "/usr/lib/openoffice" "/usr/lib/libreoffice")
FLAG=
OFFICE_HOME=
KKFILEVIEW_BIN_FOLDER=$(cd "$(dirname "$0")";pwd)
export KKFILEVIEW_BIN_FOLDER=$KKFILEVIEW_BIN_FOLDER
cd $KKFILEVIEW_BIN_FOLDER
echo "Using KKFILEVIEW_BIN_FOLDER $KKFILEVIEW_BIN_FOLDER"
grep 'office\.home' ../conf/application.properties | grep '!^#'
if [ $? -eq 0 ]; then
echo "Using customized office.home"
else
for i in ${DIR_HOME[@]}
do
if [ -f $i"/program/soffice.bin" ]; then
FLAG=true
OFFICE_HOME=${i}
break
fi
done
if [ ! -n "${FLAG}" ]; then
echo "Installing OpenOffice"
sh ../script/install.sh
else
echo "Detected office component has been installed in $OFFICE_HOME"
fi
fi
echo "Starting kkFileView..."
echo "Please check log file for more information"
nohup java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../conf/application.properties -jar kkFileView-2.0.jar > ../log/kkFileView.log 2>&1 &

View File

@@ -0,0 +1,39 @@
#######################################不可动态配置,需要重启生效#######################################
server.port = 8012
spring.http.encoding.charset = utf8
## Freemarker 配置
spring.freemarker.template-loader-path = classpath:/web/
spring.freemarker.cache = false
spring.freemarker.charset = UTF-8
spring.freemarker.check-template-location = true
spring.freemarker.content-type = text/html
spring.freemarker.expose-request-attributes = true
spring.freemarker.expose-session-attributes = true
spring.freemarker.request-context-attribute = request
spring.freemarker.suffix = .ftl
server.tomcat.uri-encoding = UTF-8
#文件上传限制
spring.http.multipart.max-request-size=100MB
spring.http.multipart.max-file-size=100MB
#文件资源路径默认为打包根路径下的file目录下
#file.dir = D:\\kkFileview\\
#openoffice home路径
#office.home = C:\\Program Files (x86)\\OpenOffice 4
#缓存实现类型不配默认为内嵌RocksDB实现可配置为redis(type = redis)实现需要配置spring.redisson.address等参数和 JDK 内置对象实现type = jdk,
#cache.type = redis
#redis连接
#spring.redisson.address = 192.168.1.204:6379
#spring.redisson.password = xxx
#######################################可在运行时动态配置#######################################
#文本类型,默认如下,可自定义添加
#simText = txt,html,xml,properties,md,java,py,c,cpp,sql
#多媒体类型,默认如下,可自定义添加
#media = mp3,wav,mp4,flv
#文件转换编码,默认根据操作系统获取
#converted.file.charset = GBK
#office类型文档(word ppt)样式,默认为图片(image)可配置为pdf预览时也有按钮切换
#office.preview.type = pdf

View File

@@ -0,0 +1,69 @@
package cn.keking.config;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
/**
* @auther: chenjh
* @time: 2019/4/10 17:22
* @description
*/
@Component
public class ConfigConstants {
private static String[] simText = {};
private static String[] media = {};
private static String convertedFileCharset;
private static String officePreviewType;
private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
public static String[] getSimText() {
return simText;
}
public static void setSimText(String[] simText) {
ConfigConstants.simText = simText;
}
public static String[] getMedia() {
return media;
}
public static void setMedia(String[] media) {
ConfigConstants.media = media;
}
public static String getConvertedFileCharset() {
return convertedFileCharset;
}
public static void setConvertedFileCharset(String convertedFileCharset) {
ConfigConstants.convertedFileCharset = convertedFileCharset;
}
public static String getOfficePreviewType() {
return officePreviewType;
}
public static void setOfficePreviewType(String officePreviewType) {
ConfigConstants.officePreviewType = officePreviewType;
}
public static String getFileDir() {
return fileDir;
}
@Value("${file.dir:default}")
public void setFileDir(String fileDir) {
if (!"default".equals(fileDir)) {
if (!fileDir.endsWith(File.separator)) {
fileDir = fileDir + File.separator;
}
ConfigConstants.fileDir = fileDir;
}
}
}

View File

@@ -0,0 +1,68 @@
package cn.keking.config;
import cn.keking.service.impl.OfficeFilePreviewImpl;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* @auther: chenjh
* @time: 2019/4/10 16:16
* @description 每隔1s读取并更新一次配置文件
*/
@Component
public class ConfigRefreshComponent {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigRefreshComponent.class);
public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
@PostConstruct
void refresh() {
Thread configRefreshThread = new Thread(new ConfigRefreshThread());
configRefreshThread.start();
}
class ConfigRefreshThread implements Runnable {
@Override
public void run() {
try {
Properties properties = new Properties();
Properties sysProperties = System.getProperties();
String text;
String media;
String convertedFileCharset = sysProperties.getProperty("sun.jnu.encoding");
String[] textArray;
String[] mediaArray;
String officePreviewType;
String configFilePath = OfficeUtils.getCustomizedConfigPath();
while (true) {
BufferedReader bufferedReader = new BufferedReader(new FileReader(configFilePath));
properties.load(bufferedReader);
text = properties.getProperty("simText", DEFAULT_TXT_TYPE);
media = properties.getProperty("media", DEFAULT_MEDIA_TYPE);
convertedFileCharset = properties.getProperty("converted.file.charset", convertedFileCharset);
officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE);
textArray = text.split(",");
mediaArray = media.split(",");
ConfigConstants.setSimText(textArray);
ConfigConstants.setMedia(mediaArray);
ConfigConstants.setConvertedFileCharset(convertedFileCharset);
ConfigConstants.setOfficePreviewType(officePreviewType);
Thread.sleep(1000L);
}
} catch (IOException | InterruptedException e) {
LOGGER.error("读取配置文件异常:{}", e);
}
}
}
}

View File

@@ -1,10 +1,9 @@
package cn.keking.config; package cn.keking.config;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec; import org.redisson.client.codec.Codec;
import org.redisson.config.Config; import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -14,6 +13,7 @@ import org.springframework.util.ClassUtils;
* Created by kl on 2017/09/26. * Created by kl on 2017/09/26.
* redisson 客户端配置 * redisson 客户端配置
*/ */
@ConditionalOnExpression("'${cache.type:default}'.equals('redis')")
@ConfigurationProperties(prefix = "spring.redisson") @ConfigurationProperties(prefix = "spring.redisson")
@Configuration @Configuration
public class RedissonConfig { public class RedissonConfig {
@@ -42,8 +42,8 @@ public class RedissonConfig {
private String codec="org.redisson.codec.JsonJacksonCodec"; private String codec="org.redisson.codec.JsonJacksonCodec";
@Bean(destroyMethod = "shutdown") @Bean
RedissonClient redisson() throws Exception { Config config() throws Exception {
Config config = new Config(); Config config = new Config();
config.useSingleServer().setAddress(address) config.useSingleServer().setAddress(address)
.setConnectionMinimumIdleSize(connectionMinimumIdleSize) .setConnectionMinimumIdleSize(connectionMinimumIdleSize)
@@ -69,7 +69,7 @@ public class RedissonConfig {
config.setThreads(thread); config.setThreads(thread);
config.setEventLoopGroup(new NioEventLoopGroup()); config.setEventLoopGroup(new NioEventLoopGroup());
config.setUseLinuxNativeEpoll(false); config.setUseLinuxNativeEpoll(false);
return Redisson.create(config); return config;
} }
public int getThread() { public int getThread() {

View File

@@ -0,0 +1,28 @@
package cn.keking.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @auther: chenjh
* @time: 2019/4/16 20:04
* @description
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
private final static Logger LOGGER = LoggerFactory.getLogger(WebConfig.class);
/**
* 访问外部文件配置
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String filePath = ConfigConstants.getFileDir();
LOGGER.info("Add resource locations: {}", filePath);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath);
super.addResourceHandlers(registry);
}
}

View File

@@ -2,9 +2,8 @@ package cn.keking.service;
import cn.keking.model.FileAttribute; import cn.keking.model.FileAttribute;
import cn.keking.model.FileType; import cn.keking.model.FileType;
import cn.keking.service.cache.CacheService;
import cn.keking.utils.FileUtils; import cn.keking.utils.FileUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +27,7 @@ public class FileConverQueueTask {
FilePreviewFactory previewFactory; FilePreviewFactory previewFactory;
@Autowired @Autowired
RedissonClient redissonClient; CacheService cacheService;
@Autowired @Autowired
FileUtils fileUtils; FileUtils fileUtils;
@@ -36,7 +35,7 @@ public class FileConverQueueTask {
@PostConstruct @PostConstruct
public void startTask(){ public void startTask(){
ExecutorService executorService = Executors.newFixedThreadPool(3); ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new ConverTask(previewFactory,redissonClient,fileUtils)); executorService.submit(new ConverTask(previewFactory,cacheService,fileUtils));
logger.info("队列处理文件转换任务启动完成 "); logger.info("队列处理文件转换任务启动完成 ");
} }
@@ -44,13 +43,13 @@ public class FileConverQueueTask {
FilePreviewFactory previewFactory; FilePreviewFactory previewFactory;
RedissonClient redissonClient; CacheService cacheService;
FileUtils fileUtils; FileUtils fileUtils;
public ConverTask(FilePreviewFactory previewFactory, RedissonClient redissonClient,FileUtils fileUtils) { public ConverTask(FilePreviewFactory previewFactory, CacheService cacheService,FileUtils fileUtils) {
this.previewFactory = previewFactory; this.previewFactory = previewFactory;
this.redissonClient = redissonClient; this.cacheService = cacheService;
this.fileUtils=fileUtils; this.fileUtils=fileUtils;
} }
@@ -58,8 +57,7 @@ public class FileConverQueueTask {
public void run() { public void run() {
while (true) { while (true) {
try { try {
final RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName); String url = cacheService.takeQueueTask();
String url = queue.take();
if(url!=null){ if(url!=null){
FileAttribute fileAttribute=fileUtils.getFileAttribute(url); FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
logger.info("正在处理转换任务,文件名称【{}】",fileAttribute.getName()); logger.info("正在处理转换任务,文件名称【{}】",fileAttribute.getName());

View File

@@ -0,0 +1,36 @@
package cn.keking.service.cache;
import java.util.List;
import java.util.Map;
/**
* @auther: chenjh
* @time: 2019/4/2 16:45
* @description
*/
public interface CacheService {
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
final String REDIS_FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
final String REDIS_FILE_PREVIEW_PDF_IMGS_KEY = "converted-preview-pdfimgs-file";
final Integer DEFAULT_PDF_CAPACITY = 500000;
final Integer DEFAULT_IMG_CAPACITY = 500000;
final Integer DEFAULT_PDFIMG_CAPACITY = 500000;
void initPDFCachePool(Integer capacity);
void initIMGCachePool(Integer capacity);
public void initPdfImagesCachePool(Integer capacity);
void putPDFCache(String key, String value);
void putImgCache(String key, List<String> value);
Map<String, String> getPDFCache();
String getPDFCache(String key);
Map<String, List<String>> getImgCache();
List<String> getImgCache(String key);
Integer getPdfImageCache(String key);
void putPdfImageCache(String pdfFilePath, int num);
void addQueueTask(String url);
String takeQueueTask() throws InterruptedException;
}

View File

@@ -0,0 +1,128 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.googlecode.concurrentlinkedhashmap.Weighers;
import org.rocksdb.RocksDB;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @auther: chenjh
* @time: 2019/4/2 17:21
* @description
*/
@Service
@ConditionalOnExpression("'${cache.type:default}'.equals('jdk')")
public class CacheServiceJDKImpl implements CacheService {
private Map<String, String> pdfCache;
private Map<String, List<String>> imgCache;
private Map<String, Integer> pdfImagesCache;
private static final int QUEUE_SIZE = 500000;
private BlockingQueue blockingQueue = new ArrayBlockingQueue(QUEUE_SIZE);
@Override
public void initPDFCachePool(Integer capacity) {
pdfCache = new ConcurrentLinkedHashMap.Builder<String, String>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void initIMGCachePool(Integer capacity) {
imgCache = new ConcurrentLinkedHashMap.Builder<String, List<String>>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
pdfImagesCache = new ConcurrentLinkedHashMap.Builder<String, Integer>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void putPDFCache(String key, String value) {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
pdfCache.put(key, value);
}
@Override
public void putImgCache(String key, List<String> value) {
if (imgCache == null) {
initIMGCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
imgCache.put(key, value);
}
@Override
public Map<String, String> getPDFCache() {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
return pdfCache;
}
@Override
public String getPDFCache(String key) {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
return pdfCache.get(key);
}
@Override
public Map<String, List<String>> getImgCache() {
if (imgCache == null) {
initPDFCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
return imgCache;
}
@Override
public List<String> getImgCache(String key) {
if (imgCache == null) {
initPDFCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
return imgCache.get(key);
}
@Override
public Integer getPdfImageCache(String key) {
if (pdfImagesCache == null) {
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
}
return pdfImagesCache.get(key);
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
if (pdfImagesCache == null) {
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
}
pdfImagesCache.put(pdfFilePath, num);
}
@Override
public void addQueueTask(String url) {
blockingQueue.add(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
return String.valueOf(blockingQueue.take());
}
}

View File

@@ -0,0 +1,108 @@
package cn.keking.service.cache.impl;
import cn.keking.service.FileConverQueueTask;
import cn.keking.service.cache.CacheService;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @auther: chenjh
* @time: 2019/4/2 18:02
* @description
*/
@ConditionalOnExpression("'${cache.type:default}'.equals('redis')")
@Service
public class CacheServiceRedisImpl implements CacheService {
private Config config;
@Autowired
public CacheServiceRedisImpl(Config config) {
this.config = config;
this.redissonClient = Redisson.create(config);
}
private RedissonClient redissonClient;
@Override
public void initPDFCachePool(Integer capacity) {
}
@Override
public void initIMGCachePool(Integer capacity) {
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
convertedList.fastPut(key, value);
}
@Override
public void putImgCache(String key, List<String> value) {
RMapCache<String, List<String>> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
convertedList.fastPut(key, value);
}
@Override
public Map<String, String> getPDFCache() {
return redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
}
@Override
public String getPDFCache(String key) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
return convertedList.get(key);
}
@Override
public Map<String, List<String>> getImgCache() {
return redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
}
@Override
public List<String> getImgCache(String key) {
RMapCache<String, List<String>> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
return convertedList.get(key);
}
@Override
public Integer getPdfImageCache(String key) {
RMapCache<String, Integer> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_IMGS_KEY);
return convertedList.get(key);
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
RMapCache<String, Integer> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_IMGS_KEY);
convertedList.fastPut(pdfFilePath, num);
}
@Override
public void addQueueTask(String url) {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
queue.addAsync(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
return queue.take();
}
}

View File

@@ -0,0 +1,203 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @auther: chenjh
* @time: 2019/4/22 11:02
* @description
*/
@ConditionalOnExpression("'${cache.type:default}'.equals('default')")
@Service
public class CacheServiceRocksDBImpl implements CacheService {
static {
RocksDB.loadLibrary();
}
private static final String DB_PATH = OfficeUtils.getHomePath() + File.separator + "cache";
private static final int QUEUE_SIZE = 500000;
private static final Logger LOGGER = LoggerFactory.getLogger(CacheServiceRocksDBImpl.class);
private BlockingQueue blockingQueue = new ArrayBlockingQueue(QUEUE_SIZE);
private RocksDB db;
{
try {
db = RocksDB.open(DB_PATH);
if (db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()) == null) {
Map<String, String> initPDFCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(initPDFCache));
}
if (db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()) == null) {
Map<String, List<String>> initIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes(), toByteArray(initIMGCache));
}
if (db.get(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes()) == null) {
Map<String, Integer> initPDFIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes(), toByteArray(initPDFIMGCache));
}
} catch (RocksDBException | IOException e) {
LOGGER.error("Uable to init RocksDB" + e);
}
}
@Override
public void initPDFCachePool(Integer capacity) {
}
@Override
public void initIMGCachePool(Integer capacity) {
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
try {
Map<String, String> pdfCacheItem = new HashMap<>();
pdfCacheItem.put(key, value);
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(pdfCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public void putImgCache(String key, List<String> value) {
try {
Map<String, List<String>> imgCacheItem = new HashMap<>();
imgCacheItem.put(key, value);
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(imgCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public Map<String, String> getPDFCache() {
Map<String, String> result = new HashMap<>();
try{
result = (Map<String, String>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public String getPDFCache(String key) {
String result = "";
try{
Map<String, String> map = (Map<String, String>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public Map<String, List<String>> getImgCache() {
Map<String, List<String>> result = new HashMap<>();
try{
result = (Map<String, List<String>>) toObject(db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public List<String> getImgCache(String key) {
List<String> result = new ArrayList<>();
Map<String, List<String>> map;
try{
map = (Map<String, List<String>>) toObject(db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public Integer getPdfImageCache(String key) {
Integer result = 0;
Map<String, Integer> map;
try{
map = (Map<String, Integer>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
try {
Map<String, Integer> pdfImageCacheItem = new HashMap<>();
pdfImageCacheItem.put(pdfFilePath, num);
db.put(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes(), toByteArray(pdfImageCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public void addQueueTask(String url) {
blockingQueue.add(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
return String.valueOf(blockingQueue.take());
}
private byte[] toByteArray (Object obj) throws IOException {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray ();
oos.close();
bos.close();
return bytes;
}
private Object toObject (byte[] bytes) throws IOException, ClassNotFoundException {
Object obj = null;
ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
ObjectInputStream ois = new ObjectInputStream (bis);
obj = ois.readObject();
ois.close();
bis.close();
return obj;
}
}

View File

@@ -38,6 +38,7 @@ public class CompressFilePreviewImpl implements FilePreview{
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) { if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName); ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
return "fileNotSupported"; return "fileNotSupported";
} }
@@ -47,14 +48,17 @@ public class CompressFilePreviewImpl implements FilePreview{
} else if ("rar".equalsIgnoreCase(suffix)) { } else if ("rar".equalsIgnoreCase(suffix)) {
fileTree = zipReader.unRar(filePath, fileName); fileTree = zipReader.unRar(filePath, fileName);
} }
fileUtils.addConvertedFile(fileName, fileTree); if (fileTree != null && !"null".equals(fileTree)) {
fileUtils.addConvertedFile(fileName, fileTree);
}
} else { } else {
fileTree = fileUtils.getConvertedFile(fileName); fileTree = fileUtils.getConvertedFile(fileName);
} }
if (null != fileTree) { if (fileTree != null && !"null".equals(fileTree)) {
model.addAttribute("fileTree", fileTree); model.addAttribute("fileTree", fileTree);
return "compress"; return "compress";
} else { } else {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", "压缩文件类型不受支持尝试在压缩的时候选择RAR4格式"); model.addAttribute("msg", "压缩文件类型不受支持尝试在压缩的时候选择RAR4格式");
return "fileNotSupported"; return "fileNotSupported";
} }

View File

@@ -1,11 +1,13 @@
package cn.keking.service.impl; package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute; import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview; import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils; import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileUtils; import cn.keking.utils.FileUtils;
import cn.keking.utils.OfficeToPdf; import cn.keking.utils.OfficeToPdf;
import cn.keking.utils.PdfUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -14,6 +16,7 @@ import org.springframework.ui.Model;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.io.File; import java.io.File;
import java.util.List;
/** /**
* Created by kl on 2018/1/17. * Created by kl on 2018/1/17.
@@ -25,8 +28,8 @@ public class OfficeFilePreviewImpl implements FilePreview {
@Autowired @Autowired
FileUtils fileUtils; FileUtils fileUtils;
@Value("${file.dir}") @Autowired
String fileDir; PdfUtils pdfUtils;
@Autowired @Autowired
DownloadUtils downloadUtils; DownloadUtils downloadUtils;
@@ -34,26 +37,36 @@ public class OfficeFilePreviewImpl implements FilePreview {
@Autowired @Autowired
private OfficeToPdf officeToPdf; private OfficeToPdf officeToPdf;
String fileDir = ConfigConstants.getFileDir();
public static final String OFFICE_PREVIEW_TYPE_PDF = "pdf";
public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
public static final String OFFICE_PREVIEW_TYPE_ALLIMAGES = "allImages";
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model) {
// 预览Type参数传了就取参数的没传取系统默认
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
String originUrl = model.asMap().get("originUrl").toString();
FileAttribute fileAttribute=fileUtils.getFileAttribute(url); FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String decodedUrl=fileAttribute.getDecodedUrl(); String decodedUrl=fileAttribute.getDecodedUrl();
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx"); boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf"); String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
String outFilePath = fileDir + pdfName;
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) { if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
String filePath = fileDir + fileName; String filePath = fileDir + fileName;
if (!new File(filePath).exists()) { if (!new File(filePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null); ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
return "fileNotSupported"; return "fileNotSupported";
} }
filePath = response.getContent(); filePath = response.getContent();
} }
String outFilePath = fileDir + pdfName;
if (StringUtils.hasText(outFilePath)) { if (StringUtils.hasText(outFilePath)) {
officeToPdf.openOfficeToPDF(filePath, outFilePath); officeToPdf.openOfficeToPDF(filePath, outFilePath);
File f = new File(filePath); File f = new File(filePath);
@@ -68,6 +81,21 @@ public class OfficeFilePreviewImpl implements FilePreview {
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath)); fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
} }
} }
if (!isHtml && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType))) {
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "office转图片异常请联系管理员");
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("imgurls", imageUrls);
model.addAttribute("currentUrl", imageUrls.get(0));
if (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType)) {
return "officePicture";
} else {
return "picture";
}
}
model.addAttribute("pdfUrl", pdfName); model.addAttribute("pdfUrl", pdfName);
return isHtml ? "html" : "pdf"; return isHtml ? "html" : "pdf";
} }

View File

@@ -1,9 +1,19 @@
package cn.keking.service.impl; package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview; import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileUtils;
import cn.keking.utils.PdfUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import java.io.File;
import java.util.List;
/** /**
* Created by kl on 2018/1/17. * Created by kl on 2018/1/17.
* Content :处理pdf文件 * Content :处理pdf文件
@@ -11,9 +21,54 @@ import org.springframework.ui.Model;
@Service @Service
public class PdfFilePreviewImpl implements FilePreview{ public class PdfFilePreviewImpl implements FilePreview{
@Autowired
FileUtils fileUtils;
@Autowired
PdfUtils pdfUtils;
@Autowired
DownloadUtils downloadUtils;
String fileDir = ConfigConstants.getFileDir();
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model) {
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName();
String officePreviewType = model.asMap().get("officePreviewType") == null ? "" : model.asMap().get("officePreviewType").toString();
String originUrl = model.asMap().get("originUrl").toString();
model.addAttribute("pdfUrl", url); model.addAttribute("pdfUrl", url);
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
String outFilePath = fileDir + pdfName;
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载
if (!new File(outFilePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
outFilePath = response.getContent();
}
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "pdf转图片异常请联系管理员");
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("imgurls", imageUrls);
model.addAttribute("currentUrl", imageUrls.get(0));
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType)) {
return "officePicture";
} else {
return "picture";
}
}
return "pdf"; return "pdf";
} }
} }

View File

@@ -5,6 +5,7 @@ import cn.keking.extend.ControlDocumentFormatRegistry;
import org.artofsolving.jodconverter.OfficeDocumentConverter; import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration; import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager; import org.artofsolving.jodconverter.office.OfficeManager;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -23,8 +24,8 @@ import java.util.Map;
@Component @Component
public class ConverterUtils { public class ConverterUtils {
@Value("${office.home}") // @Value("${office.home}")
String officeHome; // String officeHome;
// OpenOfficeConnection connection; // OpenOfficeConnection connection;
OfficeManager officeManager; OfficeManager officeManager;
@@ -32,6 +33,7 @@ public class ConverterUtils {
public void initOfficeManager() { public void initOfficeManager() {
//// connection = new SocketOpenOfficeConnection(host,8100); //// connection = new SocketOpenOfficeConnection(host,8100);
//// connection.connect(); //// connection.connect();
String officeHome = OfficeUtils.getDefaultOfficeHome().getAbsolutePath();
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration(); DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
configuration.setOfficeHome(officeHome); configuration.setOfficeHome(officeHome);
configuration.setPortNumber(8100); configuration.setPortNumber(8100);

View File

@@ -1,7 +1,7 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
@@ -13,8 +13,7 @@ import java.util.UUID;
@Component @Component
public class DownloadUtils { public class DownloadUtils {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
/** /**
* 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解 * 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解

View File

@@ -1,14 +1,13 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute; import cn.keking.model.FileAttribute;
import cn.keking.model.FileType; import cn.keking.model.FileType;
import cn.keking.service.cache.CacheService;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.*;
@@ -27,29 +26,17 @@ import java.util.Map;
public class FileUtils { public class FileUtils {
Logger log= LoggerFactory.getLogger(getClass()); Logger log= LoggerFactory.getLogger(getClass());
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
final String REDIS_FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
@Autowired @Autowired
RedissonClient redissonClient; CacheService cacheService;
@Value("${file.dir}")
String fileDir;
@Value("${converted.file.charset}") String fileDir = ConfigConstants.getFileDir();
String charset;
@Value("${simText}")
String[] simText;
@Value("${media}")
String[] media;
/** /**
* 已转换过的文件集合(redis缓存) * 已转换过的文件集合(redis缓存)
* @return * @return
*/ */
public Map<String, String> listConvertedFiles() { public Map<String, String> listConvertedFiles() {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); return cacheService.getPDFCache();
return convertedList;
} }
/** /**
@@ -57,8 +44,16 @@ public class FileUtils {
* @return * @return
*/ */
public String getConvertedFile(String key) { public String getConvertedFile(String key) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); return cacheService.getPDFCache(key);
return convertedList.get(key); }
/**
* 已将pdf转换成图片的图片本地路径
* @param key pdf本地路径
* @return
*/
public Integer getConvertedPdfImage(String key) {
return cacheService.getPdfImageCache(key);
} }
/** /**
@@ -68,6 +63,8 @@ public class FileUtils {
* @return * @return
*/ */
public FileType typeFromUrl(String url) { public FileType typeFromUrl(String url) {
String[] simText = ConfigConstants.getSimText();
String[] media = ConfigConstants.getMedia();
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length()); String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length());
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
@@ -170,8 +167,16 @@ public class FileUtils {
} }
public void addConvertedFile(String fileName, String value){ public void addConvertedFile(String fileName, String value){
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); cacheService.putPDFCache(fileName, value);
convertedList.fastPut(fileName, value); }
/**
*
* @param pdfFilePath
* @param num
*/
public void addConvertedPdfImage(String pdfFilePath, int num){
cacheService.putPdfImageCache(pdfFilePath, num);
} }
/** /**
@@ -180,8 +185,7 @@ public class FileUtils {
* @return * @return
*/ */
public List getRedisImgUrls(String fileKey){ public List getRedisImgUrls(String fileKey){
RMapCache<String, List> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY); return cacheService.getImgCache(fileKey);
return convertedList.get(fileKey);
} }
/** /**
@@ -190,8 +194,7 @@ public class FileUtils {
* @param imgs * @param imgs
*/ */
public void setRedisImgUrls(String fileKey,List imgs){ public void setRedisImgUrls(String fileKey,List imgs){
RMapCache<String, List> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY); cacheService.putImgCache(fileKey, imgs);
convertedList.fastPut(fileKey,imgs);
} }
/** /**
* 判断文件编码格式 * 判断文件编码格式
@@ -225,6 +228,7 @@ public class FileUtils {
*/ */
public void doActionConvertedFile(String outFilePath) { public void doActionConvertedFile(String outFilePath) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
String charset = ConfigConstants.getConvertedFileCharset();
try (InputStream inputStream = new FileInputStream(outFilePath); try (InputStream inputStream = new FileInputStream(outFilePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){
String line; String line;

View File

@@ -0,0 +1,66 @@
package cn.keking.utils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Component
public class PdfUtils {
private final Logger LOGGER = LoggerFactory.getLogger(PdfUtils.class);
@Autowired
FileUtils fileUtils;
public List<String> pdf2jpg(String pdfFilePath, String pdfName, String url) {
List<String> imageUrls = new ArrayList<>();
Integer imageCount = fileUtils.getConvertedPdfImage(pdfFilePath);
String imageFileSuffix = ".jpg";
// https://8个字符 http://7个字符 从这后面开始出现的第一个/就是当前file.Dir下的根目录
int index1 = url.indexOf("/", 8);
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
String urlPrefix = url.substring(0, index1 + 1) + pdfFolder;
if (imageCount != null && imageCount.intValue() > 0) {
for (int i = 0; i < imageCount ; i++)
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
return imageUrls;
}
try {
File pdfFile = new File(pdfFilePath);
PDDocument doc = PDDocument.load(pdfFile);
int pageCount = doc.getNumberOfPages();
PDFRenderer pdfRenderer = new PDFRenderer(doc);
int index = pdfFilePath.lastIndexOf(".");
String folder = pdfFilePath.substring(0, index);
File path = new File(folder);
if (!path.exists()) {
path.mkdirs();
}
String imageFilePath;
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
ImageIOUtil.writeImage(image, imageFilePath, 105);
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
}
doc.close();
fileUtils.addConvertedPdfImage(pdfFilePath, pageCount);
} catch (IOException e) {
LOGGER.error("Convert pdf to jpg exception", e);
}
return imageUrls;
}
}

View File

@@ -1,12 +1,11 @@
package cn.keking.utils; package cn.keking.utils;
import org.springframework.beans.factory.annotation.Value; import cn.keking.config.ConfigConstants;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
public class ShedulerClean { public class ShedulerClean {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
// @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次 // @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次
public void clean(){ public void clean(){

View File

@@ -1,8 +1,8 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
@@ -12,8 +12,7 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
public class SimTextUtil { public class SimTextUtil {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
@Autowired @Autowired
DownloadUtils downloadUtils; DownloadUtils downloadUtils;

View File

@@ -1,5 +1,6 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileType; import cn.keking.model.FileType;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@@ -11,7 +12,6 @@ import com.google.common.collect.Maps;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
@@ -36,8 +36,7 @@ public class ZipReader {
@Autowired @Autowired
FileUtils fileUtils; FileUtils fileUtils;
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
@@ -121,7 +120,7 @@ public class ZipReader {
List imgUrls=Lists.newArrayList(); List imgUrls=Lists.newArrayList();
String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0); String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
try { try {
Archive archive = new Archive(new File(filePath)); Archive archive = new Archive(new FileInputStream(new File(filePath)));
List<FileHeader> headers = archive.getFileHeaders(); List<FileHeader> headers = archive.getFileHeaders();
headers = sortedHeaders(headers); headers = sortedHeaders(headers);
String archiveFileName = fileUtils.getFileNameFromPath(filePath); String archiveFileName = fileUtils.getFileNameFromPath(filePath);
@@ -177,10 +176,10 @@ public class ZipReader {
private List<FileHeader> sortedHeaders(List<FileHeader> headers) { private List<FileHeader> sortedHeaders(List<FileHeader> headers) {
List<FileHeader> sortedHeaders = new ArrayList<>(); List<FileHeader> sortedHeaders = new ArrayList<>();
Map<Integer, FileHeader> mapHeaders = new TreeMap<>(); Map<Integer, FileHeader> mapHeaders = new TreeMap<>();
headers.forEach(header -> mapHeaders.put(header.getFileNameW().length(), header)); headers.forEach(header -> mapHeaders.put(new Integer(0).equals(header.getFileNameW().length()) ? header.getFileNameString().length() : header.getFileNameW().length(), header));
for (Map.Entry<Integer, FileHeader> entry : mapHeaders.entrySet()){ for (Map.Entry<Integer, FileHeader> entry : mapHeaders.entrySet()){
for (FileHeader header : headers) { for (FileHeader header : headers) {
if (entry.getKey().intValue() == header.getFileNameW().length()) { if (entry.getKey().equals(new Integer(0).equals(header.getFileNameW().length()) ? header.getFileNameString().length() : header.getFileNameW().length())) {
sortedHeaders.add(header); sortedHeaders.add(header);
} }
} }

View File

@@ -1,5 +1,6 @@
package cn.keking.web.controller; package cn.keking.web.controller;
import cn.keking.config.ConfigConstants;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@@ -7,7 +8,6 @@ import com.google.common.collect.Lists;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import cn.keking.utils.FileUtils; import cn.keking.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@@ -28,8 +28,7 @@ import java.util.UUID;
*/ */
@RestController @RestController
public class FileController { public class FileController {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
@Autowired @Autowired
FileUtils fileUtils; FileUtils fileUtils;
String demoDir = "demo"; String demoDir = "demo";

View File

@@ -1,12 +1,10 @@
package cn.keking.web.controller; package cn.keking.web.controller;
import cn.keking.service.FileConverQueueTask;
import cn.keking.service.FilePreview; import cn.keking.service.FilePreview;
import cn.keking.service.FilePreviewFactory; import cn.keking.service.FilePreviewFactory;
import cn.keking.service.cache.CacheService;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@@ -26,7 +24,6 @@ import java.net.URLConnection;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author yudian-it * @author yudian-it
@@ -38,7 +35,7 @@ public class OnlinePreviewController {
FilePreviewFactory previewFactory; FilePreviewFactory previewFactory;
@Autowired @Autowired
RedissonClient redissonClient; CacheService cacheService;
/** /**
* @param url * @param url
@@ -48,6 +45,8 @@ public class OnlinePreviewController {
@RequestMapping(value = "onlinePreview", method = RequestMethod.GET) @RequestMapping(value = "onlinePreview", method = RequestMethod.GET)
public String onlinePreview(String url, Model model, HttpServletRequest req) { public String onlinePreview(String url, Model model, HttpServletRequest req) {
req.setAttribute("fileKey", req.getParameter("fileKey")); req.setAttribute("fileKey", req.getParameter("fileKey"));
model.addAttribute("officePreviewType", req.getParameter("officePreviewType"));
model.addAttribute("originUrl",req.getRequestURL().toString());
FilePreview filePreview = previewFactory.get(url); FilePreview filePreview = previewFactory.get(url);
return filePreview.filePreviewHandle(url, model); return filePreview.filePreviewHandle(url, model);
} }
@@ -126,8 +125,7 @@ public class OnlinePreviewController {
@GetMapping("/addTask") @GetMapping("/addTask")
@ResponseBody @ResponseBody
public String addQueueTask(String url) { public String addQueueTask(String url) {
final RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName); cacheService.addQueueTask(url);
queue.addAsync(url);
return "success"; return "success";
} }

View File

View File

@@ -0,0 +1,54 @@
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0" encoding="UTF-8"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:office="http://openoffice.org/2000/office"
xmlns:style="http://openoffice.org/2000/style"
xmlns:table="http://openoffice.org/2000/table"
xmlns:draw="http://openoffice.org/2000/drawing"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="http://openoffice.org/2000/meta"
xmlns:number="http://openoffice.org/2000/datastyle"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:chart="http://openoffice.org/2000/chart"
xmlns:help="http://openoffice.org/2000/help"
xmlns:index="http://sun.com/2000/XMLSearch"
xmlns:text="http://openoffice.org/2000/text">
<xsl:param name="Language" select="'en-US'"/>
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:apply-templates select="//title" mode="include"/>
<xsl:apply-templates select="//paragraph[@role='heading']" mode="include"/>
</xsl:template>
<xsl:template match="*" mode="include">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>

View File

@@ -0,0 +1,124 @@
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0" encoding="UTF-8"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:office="http://openoffice.org/2000/office"
xmlns:style="http://openoffice.org/2000/style"
xmlns:table="http://openoffice.org/2000/table"
xmlns:draw="http://openoffice.org/2000/drawing"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="http://openoffice.org/2000/meta"
xmlns:number="http://openoffice.org/2000/datastyle"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:chart="http://openoffice.org/2000/chart"
xmlns:help="http://openoffice.org/2000/help"
xmlns:index="http://sun.com/2000/XMLSearch"
xmlns:text="http://openoffice.org/2000/text">
<xsl:param name="Language" select="'en-US'"/>
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="helpdocument|body">
<xsl:choose>
<xsl:when test="meta/topic[@indexer='exclude']"/>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="title">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="table">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="tablecell">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="tablerow">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="list">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="listitem">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="item">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="emph">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="paragraph">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="section">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="bookmark">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="bookmark_value">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="link">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="ahelp[@visibility='visible']">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ OPENOFFICE.ORG 2.0 HELP +
+ DEFAULT STYLESHEET +
+ CHINESE SIMPL +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ LAST CHANGES: 24-MAR-2005 +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ font-family: ,"MSung Light SC",SimSun,FZSongYi,FZShuSong,NSimSun,"Andale Sans UI","Arial Unicode MS","Lucida Sans Unicode",Song; }
.code, .codeintable, .example, .exampleintable, .literal, .literalintable, .path, .pathintable
{ font-family: ,"MSung Light SC",Cumberland,Courier New,Courier,"Lucida Sans Typewriter","Lucida Typewriter",Monaco,Monospaced; margin-top: 1pt; margin-bottom: 1pt;}
.acronym
{ font-weight: bold; }
.related
{ font-weight: bold; margin-top:20pt; border-top: 1px solid black;}
.emph, .menuitem, .keycode
{ font-weight: bold; }
.tablehead, .tableheadintable
{ font-weight: bold; margin-top: 0px;}
.howtogetheader
{ font-weight: bold; border: 1px solid #999999; background: #FFFFFF; padding: 3px;}
h1, h2, h3, h4, h5, h6
{ margin-bottom: 5pt; }
p, td
{ font-size: 10pt; }
h1
{ font-size: 18pt; border-bottom: 1px solid black; padding-bottom: 6px; margin-bottom: 6px;}
h2
{ font-size: 14pt; }
h3
{ font-size: 12pt; }
h4, h5, h6
{ font-size: 10pt; }
.relatedtopics
{ font-weight: normal; }
.relatedbody
{ margin-top: 2px; margin-bottom: 2px; margin-left: 5px; }
.howtoget
{ background:#EEEEEE;}
.howtogetbody
{ background:#EEEEEE;}
.wide
{ width: 100%; }
.topalign
{ vertical-align: top; border: 1px;}
.bug
{ color: red; border: 1px solid red;}
.debug
{ border: 1px solid black; padding: 3px; display: none;}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<helpdocument version="1.0">
<meta>
<topic id="textshared05err_htmlxml" indexer="exclude" status="PUBLISH">
<title id="tit" xml-lang="zh-CN">未找到帮助页面</title>
<filename>/text/shared/05/err_html.xhp</filename>
</topic>
<history>
<created date="2003-10-31T00:00:00">Sun Microsystems, Inc.</created>
<lastedited date="2005-01-11T11:07:13">converted from old format - fpe
FPE: Updated</lastedited>
</history>
</meta>
<body>
<paragraph role="heading" id="hd_id3146957" xml-lang="zh-CN" level="1" l10n="U" oldref="1">帮助页面未能找到。</paragraph>
<paragraph role="paragraph" id="par_id3147088" xml-lang="zh-CN" l10n="U" oldref="2">很遗憾,您所选择的帮助页面未能找到。以下数据可能对界定错误有所帮助:</paragraph>
<paragraph role="paragraph" id="par_id3143268" xml-lang="zh-CN" l10n="U" oldref="3">帮助 ID<emph><help-id-missing/></emph></paragraph>
<paragraph role="paragraph" id="par_idN10681" xml-lang="zh-CN" l10n="NEW">可以使用安装应用程序来安装缺少的帮助模块。</paragraph>
<paragraph role="paragraph" id="par_id3150541" xml-lang="zh-CN" l10n="U" oldref="16">单击<image id="img_id3148946" src="res/sc06301.png" width="0.222inch" height="0.222inch"><alt id="alt_id3148946">图标</alt></image><emph>上一步</emph>可返回上一页面。</paragraph>
</body>
</helpdocument>

View File

@@ -0,0 +1,114 @@
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ OPENOFFICE.ORG 2.0 HELP +
+ HIGH CONTRAST #1 STYLESHEET +
+ CHINESE SIMPL +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ LAST CHANGES: 24-MAR-2005 +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ font-family: ,"MSung Light SC",SimSun,FZSongYi,FZShuSong,NSimSun,"Andale Sans UI","Arial Unicode MS","Lucida Sans Unicode",Song; }
.code, .codeintable, .example, .exampleintable, .literal, .literalintable, .path, .pathintable
{ font-family: ,"MSung Light SC",Cumberland,Courier New,Courier,"Lucida Sans Typewriter","Lucida Typewriter",Monaco,Monospaced; margin-top: 1pt; margin-bottom: 1pt;}
.acronym
{ font-weight: bold; }
.related
{ font-weight: bold; margin-top:20pt; border-top: 1px solid black;}
.emph, .menuitem, .keycode
{ font-weight: bold; }
.tablehead, .tableheadintable
{ font-weight: bold; margin-top: 0px;}
.howtogetheader
{ font-weight: bold; padding: 3px;}
h1, h2, h3, h4, h5, h6
{ margin-bottom: 5pt; }
p, td
{ font-size: 10pt; }
h1
{ font-size: 18pt; border-bottom: 1px solid black; padding-bottom: 6px; margin-bottom: 6px;}
h2
{ font-size: 14pt; }
h3
{ font-size: 12pt; }
h4, h5, h6
{ font-size: 10pt; }
.relatedtopics
{ font-weight: normal; }
.relatedbody
{ margin-top: 2px; margin-bottom: 2px; margin-left: 5px; }
.wide
{ width: 100%; }
.topalign
{ vertical-align: top; border: 1px;}
.bug
{ color: red; border: 1px solid red;}
.debug
{ border: 1px solid black; padding: 3px; display: none;}
/* HIGH CONTRAST SPECIFIC SETTINGS */
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ background: #000000; color: #FFFF00;}
.related
{ border-top: 1px solid #FFFF00; }
.howtogetheader
{border: 1px solid #EFEFEF; background: #000000;}
h1
{ border-bottom: 1px solid #FFFF00; ]
.howtoget
{ background:#000000;}
.howtogetbody
{ background:#000000;}
.debug
{ border: 1px solid red; padding: 3px; display: none;}
a
{ color: #FFFF00; }

View File

@@ -0,0 +1,114 @@
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ OPENOFFICE.ORG 2.0 HELP +
+ HIGH CONTRAST #2 STYLESHEET +
+ CHINESE SIMPL +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ LAST CHANGES: 24-MAR-2005 +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ font-family: ,"MSung Light SC",SimSun,FZSongYi,FZShuSong,NSimSun,"Andale Sans UI","Arial Unicode MS","Lucida Sans Unicode",Song; }
.code, .codeintable, .example, .exampleintable, .literal, .literalintable, .path, .pathintable
{ font-family: ,"MSung Light SC",Cumberland,Courier New,Courier,"Lucida Sans Typewriter","Lucida Typewriter",Monaco,Monospaced; margin-top: 1pt; margin-bottom: 1pt;}
.acronym
{ font-weight: bold; }
.related
{ font-weight: bold; margin-top:20pt; border-top: 1px solid black;}
.emph, .menuitem, .keycode
{ font-weight: bold; }
.tablehead, .tableheadintable
{ font-weight: bold; margin-top: 0px;}
.howtogetheader
{ font-weight: bold; padding: 3px;}
h1, h2, h3, h4, h5, h6
{ margin-bottom: 5pt; }
p, td
{ font-size: 10pt; }
h1
{ font-size: 18pt; border-bottom: 1px solid black; padding-bottom: 6px; margin-bottom: 6px;}
h2
{ font-size: 14pt; }
h3
{ font-size: 12pt; }
h4, h5, h6
{ font-size: 10pt; }
.relatedtopics
{ font-weight: normal; }
.relatedbody
{ margin-top: 2px; margin-bottom: 2px; margin-left: 5px; }
.wide
{ width: 100%; }
.topalign
{ vertical-align: top; border: 1px;}
.bug
{ color: red; border: 1px solid red;}
.debug
{ border: 1px solid black; padding: 3px; display: none;}
/* HIGH CONTRAST SPECIFIC SETTINGS */
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ background: #000000; color: #00FF00;}
.related
{ border-top: 1px solid #00FF00; }
.howtogetheader
{border: 1px solid #EFEFEF; background: #000000;}
h1
{ border-bottom: 1px solid #00FF00; ]
.howtoget
{ background:#000000;}
.howtogetbody
{ background:#000000;}
.debug
{ border: 1px solid red; padding: 3px; display: none;}
a
{ color: #00FF00; }

View File

@@ -0,0 +1,114 @@
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ OPENOFFICE.ORG 2.0 HELP +
+ HIGH CONTRAST BLACK STYLESHEET +
+ CHINESE SIMPL +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ LAST CHANGES: 24-MAR-2005 +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ font-family: ,"MSung Light SC",SimSun,FZSongYi,FZShuSong,NSimSun,"Andale Sans UI","Arial Unicode MS","Lucida Sans Unicode",Song; }
.code, .codeintable, .example, .exampleintable, .literal, .literalintable, .path, .pathintable
{ font-family: ,"MSung Light SC",Cumberland,Courier New,Courier,"Lucida Sans Typewriter","Lucida Typewriter",Monaco,Monospaced; margin-top: 1pt; margin-bottom: 1pt;}
.acronym
{ font-weight: bold; }
.related
{ font-weight: bold; margin-top:20pt; border-top: 1px solid black;}
.emph, .menuitem, .keycode
{ font-weight: bold; }
.tablehead, .tableheadintable
{ font-weight: bold; margin-top: 0px;}
.howtogetheader
{ font-weight: bold; padding: 3px;}
h1, h2, h3, h4, h5, h6
{ margin-bottom: 5pt; }
p, td
{ font-size: 10pt; }
h1
{ font-size: 18pt; border-bottom: 1px solid black; padding-bottom: 6px; margin-bottom: 6px;}
h2
{ font-size: 14pt; }
h3
{ font-size: 12pt; }
h4, h5, h6
{ font-size: 10pt; }
.relatedtopics
{ font-weight: normal; }
.relatedbody
{ margin-top: 2px; margin-bottom: 2px; margin-left: 5px; }
.wide
{ width: 100%; }
.topalign
{ vertical-align: top; border: 1px;}
.bug
{ color: red; border: 1px solid red;}
.debug
{ border: 1px solid black; padding: 3px; display: none;}
/* HIGH CONTRAST SPECIFIC SETTINGS */
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ background: #000000; color: #FFFFFF;}
.related
{ border-top: 1px solid #FFFFFF; }
.howtogetheader
{border: 1px solid #FFFFFF; background: #000000;}
h1
{ border-bottom: 1px solid #FFFFFF; ]
.howtoget
{ background:#000000;}
.howtogetbody
{ background:#000000;}
.debug
{ border: 1px solid red; padding: 3px; display: none;}
a
{ color: #FFFFFF; }

View File

@@ -0,0 +1,114 @@
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ OPENOFFICE.ORG 2.0 HELP +
+ HIGH CONTRAST WHITE STYLESHEET +
+ CHINESE SIMPL +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ LAST CHANGES: 24-MAR-2005 +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ font-family: ,"MSung Light SC",SimSun,FZSongYi,FZShuSong,NSimSun,"Andale Sans UI","Arial Unicode MS","Lucida Sans Unicode",Song; }
.code, .codeintable, .example, .exampleintable, .literal, .literalintable, .path, .pathintable
{ font-family: ,"MSung Light SC",Cumberland,Courier New,Courier,"Lucida Sans Typewriter","Lucida Typewriter",Monaco,Monospaced; margin-top: 1pt; margin-bottom: 1pt;}
.acronym
{ font-weight: bold; }
.related
{ font-weight: bold; margin-top:20pt; border-top: 1px solid black;}
.emph, .menuitem, .keycode
{ font-weight: bold; }
.tablehead, .tableheadintable
{ font-weight: bold; margin-top: 0px;}
.howtogetheader
{ font-weight: bold; padding: 3px;}
h1, h2, h3, h4, h5, h6
{ margin-bottom: 5pt; }
p, td
{ font-size: 10pt; }
h1
{ font-size: 18pt; border-bottom: 1px solid black; padding-bottom: 6px; margin-bottom: 6px;}
h2
{ font-size: 14pt; }
h3
{ font-size: 12pt; }
h4, h5, h6
{ font-size: 10pt; }
.relatedtopics
{ font-weight: normal; }
.relatedbody
{ margin-top: 2px; margin-bottom: 2px; margin-left: 5px; }
.wide
{ width: 100%; }
.topalign
{ vertical-align: top; border: 1px;}
.bug
{ color: red; border: 1px solid red;}
.debug
{ border: 1px solid black; padding: 3px; display: none;}
/* HIGH CONTRAST SPECIFIC SETTINGS */
body, p, h1, h2, h3, h4, h5, h6, .listitem, .listitemintable, .tablecontent, .tablecontentintable
{ background: #FFFFFF; color: #000000;}
.related
{ border-top: 1px solid #000000; }
.howtogetheader
{border: 1px solid #000000; background: #FFFFFF;}
h1
{ border-bottom: 1px solid #000000; ]
.howtoget
{ background:#FFFFFF;}
.howtogetbody
{ background:#FFFFFF;}
.debug
{ border: 1px solid red; padding: 3px; display: none;}
a
{ color: #000000; }

View File

@@ -0,0 +1,30 @@
###############################################################
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
###############################################################
Title=%PRODUCTNAME Basic
Language=zh-CN
Order=7
Start=text%2Fsbasic%2Fshared%2Fmain0601.xhp
Heading=headingheading
Program=BASIC
07.07.04 00:00:00

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<tree_view version="24-Aug-2004">
<help_section application="sbasic" id="07" title="宏和编程">
<node id="0701" title="一般信息和用户界面的使用">
<topic id="sbasic/text/sbasic/shared/main0601.xhp">%PRODUCTNAME Basic 帮助</topic>
<topic id="sbasic/text/sbasic/shared/01000000.xhp">使用 %PRODUCTNAME Basic 编程</topic>
<topic id="sbasic/text/sbasic/shared/00000002.xhp">%PRODUCTNAME Basic 词汇表</topic>
<topic id="sbasic/text/sbasic/shared/01010210.xhp">Basics</topic>
<topic id="sbasic/text/sbasic/shared/01020000.xhp">语法</topic>
<topic id="sbasic/text/sbasic/shared/01050000.xhp">%PRODUCTNAME Basic IDE</topic>
<topic id="sbasic/text/sbasic/shared/01030100.xhp">IDE 概况</topic>
<topic id="sbasic/text/sbasic/shared/01030200.xhp">Basic 编辑器</topic>
<topic id="sbasic/text/sbasic/shared/01050100.xhp">监视窗口</topic>
<topic id="sbasic/text/sbasic/shared/main0211.xhp">宏工具栏</topic>
<topic id="sbasic/text/sbasic/shared/05060700.xhp">宏</topic>
</node>
<node id="0702" title="命令引用">
<topic id="sbasic/text/sbasic/shared/01020300.xhp">使用过程和函数</topic>
<topic id="sbasic/text/sbasic/shared/01020500.xhp">程序库、模块和对话框</topic>
<node id="070202" title="运行时函数、语句和运算符">
<topic id="sbasic/text/sbasic/shared/03010000.xhp">屏幕 I/O 函数</topic>
<topic id="sbasic/text/sbasic/shared/03020000.xhp">文件 I/O 函数</topic>
<topic id="sbasic/text/sbasic/shared/03030000.xhp">日期和时间函数</topic>
<topic id="sbasic/text/sbasic/shared/03050000.xhp">错误处理函数</topic>
<topic id="sbasic/text/sbasic/shared/03060000.xhp">逻辑运算符</topic>
<topic id="sbasic/text/sbasic/shared/03070000.xhp">数学运算符</topic>
<topic id="sbasic/text/sbasic/shared/03080000.xhp">数字函数</topic>
<topic id="sbasic/text/sbasic/shared/03090000.xhp">控制程序的执行</topic>
<topic id="sbasic/text/sbasic/shared/03100000.xhp">变量</topic>
<topic id="sbasic/text/sbasic/shared/03110000.xhp">比较运算符</topic>
<topic id="sbasic/text/sbasic/shared/03120000.xhp">字符串</topic>
<topic id="sbasic/text/sbasic/shared/03130000.xhp">其他命令</topic>
</node>
<node id="070201" title="函数、语句和运算符的字母顺序列表">
<topic id="sbasic/text/sbasic/shared/03080601.xhp">Abs 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060100.xhp">AND 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104200.xhp">Array 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120101.xhp">Asc 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080101.xhp">Atn 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03130100.xhp">Beep 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010301.xhp">Blue 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100100.xhp">CBool 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120105.xhp">CByte 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030108.xhp">CDateFromIso 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030107.xhp">CdateToIso 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100300.xhp">CDate 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100400.xhp">CDbl 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100500.xhp">CInt 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100600.xhp">CLng 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100900.xhp">CSng 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101000.xhp">CStr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090401.xhp">Call 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020401.xhp">ChDir 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020402.xhp">ChDrive 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090402.xhp">Choose 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120102.xhp">Chr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020101.xhp">Close 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03110100.xhp">比较运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03100700.xhp">Const 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120313.xhp">ConvertFromURL 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120312.xhp">ConvertToURL 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080102.xhp">Cos 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131800.xhp">CreateUnoDialog 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03132000.xhp">CreateUnoListener 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131600.xhp">CreateUnoService 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131500.xhp">CreateUnoStruct 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020403.xhp">CurDir 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030101.xhp">DateSerial 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030102.xhp">DateValue 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030301.xhp">Date 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030103.xhp">Day 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090403.xhp">Declare 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101100.xhp">DefBool 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101300.xhp">DefDate 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101400.xhp">DefDbl 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101500.xhp">DefInt 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101600.xhp">DefLng 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03101700.xhp">DefObj 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102000.xhp">DefVar 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104300.xhp">DimArray 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102100.xhp">Dim 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020404.xhp">Dir 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090201.xhp">Do...Loop 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03110100.xhp">比较运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090404.xhp">End 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03130800.xhp">Environ 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020301.xhp">Eof 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104600.xhp">EqualUnoObjects 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060200.xhp">Eqv 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03050100.xhp">Erl 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03050200.xhp">Err 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03050300.xhp">Error 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03050000.xhp">错误处理函数</topic>
<topic id="sbasic/text/sbasic/shared/03090412.xhp">Exit 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080201.xhp">Exp 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020405.xhp">FileAttr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020406.xhp">FileCopy 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020407.xhp">FileDateTime 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020415.xhp">FileExists 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020408.xhp">FileLen 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103800.xhp">FindObject 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103900.xhp">FindPropertyObject 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080501.xhp">Fix 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090202.xhp">For...Next 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120301.xhp">Format 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020102.xhp">FreeFile 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090405.xhp">FreeLibrary 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090406.xhp">Function 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090400.xhp">其他语句</topic>
<topic id="sbasic/text/sbasic/shared/03080300.xhp">生成随机数</topic>
<topic id="sbasic/text/sbasic/shared/03020409.xhp">GetAttr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131700.xhp">GetProcessServiceManager 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131000.xhp">GetSolarVersion 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03130700.xhp">GetSystemTicks 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020201.xhp">Get 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131900.xhp">GlobalScope [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090301.xhp">GoSub...Return 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090302.xhp">GoTo 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010302.xhp">Green 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104400.xhp">HasUnoInterfaces 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080801.xhp">Hex 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030201.xhp">Hour 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090103.xhp">IIf 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090101.xhp">If...Then...Else 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060300.xhp">隐含运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120401.xhp">InStr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010201.xhp">InputBox 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020202.xhp">Input# 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080502.xhp">Int 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102200.xhp">IsArray 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102300.xhp">IsDate 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102400.xhp">IsEmpty 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104000.xhp">IsMissing 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102600.xhp">IsNull 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102700.xhp">IsNumeric 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102800.xhp">IsObject 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104500.xhp">IsUnoStruct 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120315.xhp">Join 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020410.xhp">Kill 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102900.xhp">LBound 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120302.xhp">LCase 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120304.xhp">LSet 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120305.xhp">LTrim 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120303.xhp">Left 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120402.xhp">Len 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103100.xhp">Let 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020203.xhp">Line Input # 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020302.xhp">Loc 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020303.xhp">Lof 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080202.xhp">Log 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120306.xhp">Mid 函数、Mid 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030202.xhp">Minute 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020411.xhp">MkDir 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070600.xhp">Mod 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030104.xhp">Month 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010102.xhp">MsgBox 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010101.xhp">MsgBox 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020412.xhp">Name 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060400.xhp">"Not"运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030203.xhp">Now 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080000.xhp">数字函数</topic>
<topic id="sbasic/text/sbasic/shared/03080802.xhp">Oct 函数 [运行时间]</topic>
<topic id="sbasic/text/sbasic/shared/03050500.xhp">On Error GoTo ...Resume 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090303.xhp">On...GoSub 语句On...GoTo 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020103.xhp">Open 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103200.xhp">Option Base 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103300.xhp">Option Explicit 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03104100.xhp">Optional在函数语句中[运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060500.xhp">Or 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010103.xhp">Print 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103400.xhp">Public 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020204.xhp">Put 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010304.xhp">QBColor 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010305.xhp">RGB 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120308.xhp">RSet 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120309.xhp">RTrim 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080301.xhp">Randomize 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03102101.xhp">ReDim 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03010303.xhp">Red 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090407.xhp">Rem 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020104.xhp">Reset 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120307.xhp">Right 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020413.xhp">RmDir 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080302.xhp">Rnd 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030204.xhp">Second 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020304.xhp">Seek 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020305.xhp">Seek 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090102.xhp">Select...Case 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020414.xhp">SetAttr 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103700.xhp">Set 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080701.xhp">Sgn 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03130500.xhp">Shell 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080103.xhp">Sin 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120201.xhp">Space 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120314.xhp">Split 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080401.xhp">Sqr 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080400.xhp">计算平方根</topic>
<topic id="sbasic/text/sbasic/shared/03103500.xhp">Static 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090408.xhp">Stop 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120403.xhp">StrComp 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120103.xhp">Str 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120202.xhp">String 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090409.xhp">Sub 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090410.xhp">Switch 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080104.xhp">Tan 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030205.xhp">TimeSerial 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030206.xhp">TimeValue 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030302.xhp">Time 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030303.xhp">Timer 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03080100.xhp">三角函数</topic>
<topic id="sbasic/text/sbasic/shared/03120311.xhp">Trim 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131300.xhp">TwipsPerPixelX 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03131400.xhp">TwipsPerPixelY 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103600.xhp">TypeName 函数; VarType 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03103000.xhp">UBound 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120310.xhp">UCase 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03120104.xhp">Val 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03130600.xhp">Wait 语句 [运行时间]</topic>
<topic id="sbasic/text/sbasic/shared/03030105.xhp">WeekDay 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090203.xhp">While...Wend 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03090411.xhp">With 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03020205.xhp">Write 语句 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03060600.xhp">Xor 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03030106.xhp">Year 函数 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070100.xhp">"-" 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070200.xhp">"*" 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070300.xhp">"+" 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070400.xhp">"/" 运算符 [运行时]</topic>
<topic id="sbasic/text/sbasic/shared/03070500.xhp">"^" 运算符 [运行时]</topic>
</node>
</node>
<node id="0703" title="指南">
<topic id="sbasic/text/sbasic/guide/control_properties.xhp">修改对话框编辑器中控件的属性</topic>
<topic id="sbasic/text/sbasic/guide/insert_control.xhp">在对话框编辑器中创建控件</topic>
<topic id="sbasic/text/sbasic/guide/sample_code.xhp">对话框编辑器中控件的编程示例</topic>
<topic id="sbasic/text/sbasic/guide/show_dialog.xhp">通过程序代码打开对话框</topic>
<topic id="sbasic/text/sbasic/guide/create_dialog.xhp">创建 Basic 对话框</topic>
<topic id="sbasic/text/sbasic/shared/01030400.xhp">管理库和模块</topic>
<topic id="sbasic/text/sbasic/shared/01020100.xhp">使用变量</topic>
<topic id="sbasic/text/sbasic/shared/01020200.xhp">使用对象</topic>
<topic id="sbasic/text/sbasic/shared/01030300.xhp">调试 Basic 程序</topic>
<topic id="sbasic/text/sbasic/shared/01040000.xhp">事件驱动的宏</topic>
</node>
</help_section>
</tree_view>

Some files were not shown because too many files have changed in this diff Show More