Compare commits

...

No commits in common. "3.6.0" and "master" have entirely different histories.

4410 changed files with 2437 additions and 969049 deletions

15
.eslintrc.yml Normal file
View File

@ -0,0 +1,15 @@
plugins:
- jasmine
env:
commonjs: true
es6: true
node: true
jasmine: true
extends:
- airbnb-base
globals:
Atomics: readonly
SharedArrayBuffer: readonly
parserOptions:
ecmaVersion: 2018
rules: {}

5
.gitattributes vendored
View File

@ -1,5 +0,0 @@
*.css linguist-language=java
*.less linguist-language=java
*.js linguist-language=java
*.html linguist-language=java
*.* linguist-language=java

11
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,11 @@
name: CI
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- run: npm install
- run: npm test

32
.gitignore vendored
View File

@ -1,30 +1,2 @@
target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
nbproject/private/
nbbuild/
dist/
nbdist/
.nb-gradle/
/*.iml
### VS Code ###
.vscode/
server/src/main/cache/
server/src/main/file/
node_modules/
*.swp

View File

@ -1,41 +0,0 @@
FROM ubuntu:20.04
MAINTAINER chenjh "842761733@qq.com"
ADD server/target/kkFileView-*.tar.gz /opt/
COPY fonts/* /usr/share/fonts/chienes/
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" > /etc/apt/sources.list &&\
apt-get clean && apt-get update &&\
apt-get install -y locales && apt-get install -y language-pack-zh-hans &&\
localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 &&\
apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
apt-get install -y libxrender1 && apt-get install -y libxt6 && apt-get install -y libxext-dev && apt-get install -y libfreetype6-dev &&\
apt-get install -y wget && apt-get install -y ttf-mscorefonts-installer && apt-get install -y fontconfig &&\
apt-get install ttf-wqy-microhei &&\
apt-get install ttf-wqy-zenhei &&\
apt-get install xfonts-wqy &&\
cd /tmp &&\
wget https://kkfileview.keking.cn/server-jre-8u251-linux-x64.tar.gz &&\
tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ &&\
# 安装 OpenOffice
wget https://kkfileview.keking.cn/Apache_OpenOffice_4.1.6_Linux_x86-64_install-deb_zh-CN.tar.gz -cO openoffice_deb.tar.gz &&\
tar -zxf /tmp/openoffice_deb.tar.gz && cd /tmp/zh-CN/DEBS &&\
dpkg -i *.deb && dpkg -i desktop-integration/openoffice4.1-debian-menus_4.1.6-9790_all.deb &&\
# 安装 libreoffice
# apt-get install -y libxinerama1 libcairo2 libcups2 libx11-xcb1 &&\
# wget https://mirrors.cloud.tencent.com/libreoffice/libreoffice/stable/7.1.3/deb/x86_64/LibreOffice_7.1.3_Linux_x86-64_deb.tar.gz -cO libreoffice_deb.tar.gz &&\
# tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.1.3.2_Linux_x86-64_deb/DEBS &&\
# dpkg -i *.deb &&\
rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* &&\
cd /usr/share/fonts/chienes &&\
mkfontscale &&\
mkfontdir &&\
fc-cache -fv
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
ENV LANG zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.6.0/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.6.0/config/application.properties","-jar","/opt/kkFileView-3.6.0/bin/kkFileView-3.6.0.jar"]

214
LICENSE
View File

@ -1,201 +1,21 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2017 Casey Lee
1. Definitions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,166 +0,0 @@
# file-online-preview
[![GitHub license](https://img.shields.io/github/license/kekingcn/kkFileView.svg?style=flat-square)](https://github.com/kekingcn/kkFileView/blob/master/LICENSE)
### Introduction
This kekingcn kkFileView project is intended to be a solution for previewing documents online. At present,there are some similar paid products in the industry.
Such as 【[永中office](http://dcs.yozosoft.com/)】,【[office365](http://www.officeweb365.com/)】,【[idocv](https://www.idocv.com/)】, etc...
It is an open source implementation and released under the Apache License version 2.0. Finally,It is aimed to feedback the community after obtaining the consent of company executives,
special thanks to the supports of @唐老大 and the contributions of @端木详笑.
### Features
- Build with the popular frame spring boot
- Easy to build and deploy
- Basically support online preview of mainstream office documents, such as Doc, docx, Excel, PDF, TXT, zip, rar, pictures, etc
- REST API
- Abstract file preview interface so that it is easy to extend more file extensions and develop this project on your own
### Official website and DOCS
URL[https://kkfileview.keking.cn](https://kkfileview.keking.cn)
### Live demo
> Please treat public service kindly, or this would stop at any time.
URL[https://file.keking.cn](https://file.keking.cn)
### Documentation
1. Full wiki documenthttps://gitee.com/kekingcn/file-online-preview/wikis/pages
1. 中文文档https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
1. English documenthttps://gitee.com/kekingcn/file-online-preview/blob/master/README.en.md
### Contact us && Join us
> We will answer everyone's questions in use of this project.
And please Google or Baidu first before asking a question, so that we can solve it efficiently.
Cherish life away from ineffective communication.
![输入图片说明](https://gitee.com/uploads/images/2017/1219/173717_934cb068_492218.png "屏幕截图.png")
QQ group613025121
### Pictures for some samples
#### 1. Text Preview
It supports preview of all types of text documents. Because there are too many types of text documents, it is impossible to enumerate them. The default open types are as follows: txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd
The text preview effect is as follows
![text](https://kkfileview.keking.cn/img/preview/preview-text.png)
#### 2. Picture preview
Support jpg, jpeg, png, gif and other picture previews (flip, zoom, mirror). The preview effect is as follows
![image](https://kkfileview.keking.cn/img/preview/preview-image.png)
#### 3. Word document preview
Doc and docx document previews are supported. There are two modes of word previews: one is that each page of word is converted to picture previews, the other is that the whole word document is converted to PDF, and then previews PDF. The applicable scenarios of the two modes are as follows
* Picture preview modes: the word file is large, and the whole PDF loaded in the foreground is too slow
* Pdf Preview modes: intranet access, loading PDF fast
The preview effect of picture preview mode is as follows
![word1](https://kkfileview.keking.cn/img/preview/preview-doc-image.png)
The preview effect of PDF preview mode is as follows
![word2](https://kkfileview.keking.cn/img/preview/preview-doc-pdf.png)
#### 4. PPT document preview
ppt and pptx document preview are supported. Like word documents, there are two preview modes
The preview effect of picture preview mode is as follows
![ppt1](https://kkfileview.keking.cn/img/preview/preview-ppt-image.png)
The preview effect of PDF preview mode is as follows
![ppt2](https://kkfileview.keking.cn/img/preview/preview-ppt-pdf.png)
#### 5. PDF document preview
Pdf document preview is supported. Like word document, there are two preview modes
The preview effect of picture preview mode is as follows
![pdf1](https://kkfileview.keking.cn/img/preview/preview-pdf-image.png)
The preview effect of PDF preview mode is as follows
![pdf2](https://kkfileview.keking.cn/img/preview/preview-pdf-pdf.png)
#### 6. EXCEL document preview
Support XLS, xlsx document preview, the preview effect is as follows
![excel](https://kkfileview.keking.cn/img/preview/preview-xls.png)
#### 7. Compressed file Preview
Support zip, rar, jar, tar, gzip and other compressed packages. The preview effect is as follows
![compress1](https://kkfileview.keking.cn/img/preview/preview-zip.png)
Click the file name in the compressed package to preview the file directly. The preview effect is as follows
![compress2](https://kkfileview.keking.cn/img/preview/preview-zip-inner.png)
#### 8. Multimedia file Preview
Theoretically, all video and audio files are supported. Since all file formats cannot be enumerated, the default open type is as follows
mp3,wav,mp4,flv
The video preview effect is as follows
![media1](https://kkfileview.keking.cn/img/preview/preview-video.png)
The audio preview effect is as follows
![media2](https://kkfileview.keking.cn/img/preview/preview-audio.png)
#### 9. CAD document preview
CAD DWG document preview is supported. Like word document, there are two preview modes
The preview effect of Picture preview mode is as follows
![cad1](https://kkfileview.keking.cn/img/preview/preview-cad-image.png)
The preview effect of PDF preview mode is as follows
![cad2](https://kkfileview.keking.cn/img/preview/preview-cad-pdf.png)
Considering space issues, the pictures of other types of documents will not be shown here.You can deploy it by yourself if you are interested in our project.There is a way to deploy it as below.
### Quick Start
> Technology stack
- Spring boot [spring boot Development Reference Guide](http://www.kailing.pub/PdfReader/web/viewer.html?file=springboot)
- Freemarker
- Redisson
- Jodconverter
> Dependencies
- Redis(Optional, Unnecessary by default)
- OpenOffice or LibreOffice(Integrated on Windows, will be installed automatically on Linux, need to be manually installed on Mac OS)
1. First step`git pull https://github.com/kekingcn/file-online-preview.git`
2. Third stepRun the main method of FilePreviewApplication.java.After starting,visit `http://localhost:8012/`.
If everything is ok,you will see the picture below.
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### Changelog
> May 20th 2020
1. Support for global watermark and dynamic change of watermark content through parameters
2. Support for CAD file Preview
3. Add configuration item base.url, support using nginx reverse proxy and set context-path
4. All configuration items can be read from environment variables, which is convenient for docker image deployment and large-scale use in cluster
5. Support the configuration of TrustHost (only the file source from the trust site can be previewed), and protect the preview service from abuse
6. Support configuration of customize cache cleanup time (cron expression)
7. All recognizable plain text can be previewed directly without downloading, such as .md .java .py, etc
8. Support configuration to limit PDF file download after conversion
9. Optimize Maven packaging configuration to solve the problem of line break in .sh script
10. Place all CDN dependencies on the front end locally for users without external network connection
11. Comment Service on home page switched from Sohu ChangYan to gitalk
12. Fixed preview exceptions that may be caused by special characters in the URL
13. Fixed the addtask exception of the transformation file queue
14. Fixed other known issues
15. Official website build: [https://kkfileview.keking.cn](https://kkfileview.keking.cn)
16. Official docker image repository build: [https://hub.docker.com/r/keking/kkfileview](https://hub.docker.com/r/keking/kkfileview)
> June 18th 2019
1. Support automatic cleaning of cache and preview files
2. Support http/https stream url file preview
3. Support FTP url file preview
4. Add Docker build
> 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
1. Refined the project directory, abstract file preview interface, Easy to extend more file extensions and depoly this project on your own
1. Added English documentation (@幻幻Fate@汝辉) contribution
1. Support for more image file extensions
1. Fixed the issue that image carousel in zip file will always start from the first
> January 12th 2018
1. Support for multiple images preview
1. Support for images rotation preview in rar/zip
> January 2nd 2018
1. Fixed gibberish issue when preview a txt document caused by the file encoding problem
1. Fixed the issue that some module dependencies can not be found
1. Add a spring boot profile, and support for Multi-environment configuration
1. Add `pdf.js` to preview the documents such as doc,etc.,support for generating doc headlines as pdf menusupport for mobile preview
### Register Usage
If this project is helpful for you, please register on 'https://gitee.com/kekingcn/file-online-preview/issues/IGSBV',
If this project helps you to economize the service charge for preview of documents, as well as you are willing to support us, click 【donate】 below to donate a cup of coffee, we would appreciate it.

231
README.md
View File

@ -1,227 +1,12 @@
# file-online-preview
此项目为文件文档在线预览项目解决方案,对标业内付费产品有【[永中office](http://dcs.yozosoft.com/)】【[office365](http://www.officeweb365.com/)】【[idocv](https://www.idocv.com/)】等在取得公司高层同意后以Apache协议开源出来反哺社区在此特别感谢@唐老大的支持以及@端木详笑的贡献。该项目使用流行的spring boot搭建易上手和部署基本支持主流办公文档的在线预览如doc,docx,Excel,pdf,txt,zip,rar,图片等等
### 项目特性
# Overview
Simple Node.js application to demonstrate the use of GitHub Actions
1. 支持 office, pdf, cad 等办公文档
1. 支持 txt, xml(渲染), md(渲染), java, php, py, js, css 等所有纯文本
1. 支持 zip, rar, jar, tar, gzip 等压缩包
1. 支持 jpg, jpeg, png, gif, tif, tiff 等图片预览(翻转,缩放,镜像)
1. 使用 spring-boot 开发,预览服务搭建部署非常简便
1. rest 接口提供服务,跨语言、跨平台特性(java,php,python,go,php....)都支持,应用接入简单方便
1. 抽象预览服务接口,方便二次开发,非常方便添加其他类型文件预览支持
1. 最最重要 Apache 协议开源,代码 pull 下来想干嘛就干嘛
# Look Ma, no Makefile!
All the tasks necessary for testing, building and deploying this code is already defined in `.github/workflows/` so why would you want to also create a `Makefile` for local development? Now you can use [act](https://github.com/nektos/act) to run the actions locally!
### 官网及文档
Try these:
地址:[https://kkfileview.keking.cn](https://kkfileview.keking.cn)
* `act -j test` - run the tests
* `act` - run the the entire pipeline
* `act -l` - view the execution graph
### 在线体验
> 请善待公共服务,会不定时停用
地址:[https://file.keking.cn](https://file.keking.cn)
### 项目文档Project documentation
1. 详细wiki文档https://gitee.com/kekingcn/file-online-preview/wikis/pages
1. 中文文档https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
1. English documenthttps://gitee.com/kekingcn/file-online-preview/blob/master/README.en.md
### 联系我们,加入组织
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少 Google 或 baidu 过,珍爱生命远离无效的交流沟通
![](./doc/KK开源技术交流2群群聊二维码.png)
QQ群号~~613025121(已满)~~ 2群484680571
### 文档预览效果
#### 1. 文本预览
支持所有类型的文本文档预览, 由于文本文档类型过多,无法全部枚举,默认开启的类型如下 txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd
文本预览效果如下
![文本预览效果如下](https://kkfileview.keking.cn/img/preview/preview-text.png)
#### 2. 图片预览
支持jpgjpegpnggif等图片预览翻转缩放镜像预览效果如下
![图片预览](https://kkfileview.keking.cn/img/preview/preview-image.png)
#### 3. word文档预览
支持docdocx文档预览word预览有两种模式一种是每页word转为图片预览另一种是整个word文档转成pdf再预览pdf。两种模式的适用场景如下
* 图片预览word文件大前台加载整个pdf过慢
* pdf预览内网访问加载pdf快
图片预览模式预览效果如下
![word文档预览1](https://kkfileview.keking.cn/img/preview/preview-doc-image.png)
pdf预览模式预览效果如下
![word文档预览2](https://kkfileview.keking.cn/img/preview/preview-doc-pdf.png)
#### 4. ppt文档预览
支持pptpptx文档预览和word文档一样有两种预览模式
图片预览模式预览效果如下
![ppt文档预览1](https://kkfileview.keking.cn/img/preview/preview-ppt-image.png)
pdf预览模式预览效果如下
![ppt文档预览2](https://kkfileview.keking.cn/img/preview/preview-ppt-pdf.png)
#### 5. pdf文档预览
支持pdf文档预览和word文档一样有两种预览模式
图片预览模式预览效果如下
![pdf文档预览1](https://kkfileview.keking.cn/img/preview/preview-pdf-image.png)
pdf预览模式预览效果如下
![pdf文档预览2](https://kkfileview.keking.cn/img/preview/preview-pdf-pdf.png)
#### 6. excel文档预览
支持xlsxlsx文档预览预览效果如下
![excel文档预览](https://kkfileview.keking.cn/img/preview/preview-xls.png)
#### 7. 压缩文件预览
支持zip,rar,jar,tar,gzip等压缩包预览效果如下
![压缩文件预览1](https://kkfileview.keking.cn/img/preview/preview-zip.png)
可点击压缩包中的文件名,直接预览文件,预览效果如下
![压缩文件预览2](https://kkfileview.keking.cn/img/preview/preview-zip-inner.png)
#### 8. 多媒体文件预览
理论上支持所有的视频、音频文件,由于无法枚举所有文件格式,默认开启的类型如下
mp3,wav,mp4,flv
视频预览效果如下
![多媒体文件预览1](https://kkfileview.keking.cn/img/preview/preview-video.png)
音频预览效果如下
![多媒体文件预览2](https://kkfileview.keking.cn/img/preview/preview-audio.png)
#### 9. CAD文档预览
支持CAD dwg文档预览和word文档一样有两种预览模式
图片预览模式预览效果如下
![cad文档预览1](https://kkfileview.keking.cn/img/preview/preview-cad-image.png)
pdf预览模式预览效果如下
![cad文档预览2](https://kkfileview.keking.cn/img/preview/preview-cad-pdf.png)
考虑说明篇幅原因,就不贴其他格式文件的预览效果了,感兴趣的可以参考下面的实例搭建下
### 快速开始
> 项目使用技术
- spring boot [spring boot开发参考指南](http://www.kailing.pub/PdfReader/web/viewer.html?file=springboot)
- freemarker
- redisson
- jodconverter
> 依赖外部环境
- redis (可选,默认不用)
- OpenOffice 或者 LibreOffice( Windows 下已内置Linux 脚本启动模式会自动安装Mac OS 下需要手动安装)
1. 第一步pull 项目 https://github.com/kekingcn/file-online-preview.git
3. 第二步:运行 ServerMain 的 main 方法,服务启动后,访问 http://localhost:8012/
会看到如下界面,代表服务启动成功
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### 历史更新记录
> 2021年6月17日v3.6.0 版本发布
ofd 类型文件支持版本,本次版本重要功能均由社区开发贡献,感谢 @gaoxingzaq、@zhangxiaoxiao9527 的代码贡献
1. 新增 ofd 类型文件预览支持ofd 是国产的类似 pdf 格式的文件
2. 新增了 ffmpeg 视频文件转码预览支持,打开转码功能后,理论上支持所有主流视频的预览,如 rm、rmvb、flv 等
3. 美化了 ppt、pptx 类型文件预览效果,比之前版本好看太多
4. 更新了 pdfbox、xstream、common-io 等依赖的版本
> 2021年1月28日
2020农历年最后一个版本发布主要包含了部分 UI 改进,和解决了 QQ 群友、 Issue 里反馈的 Bug 修复,最最重要的是发个新版,过个好年
1. 引入galimatias,解决不规范文件名导致文件下载异常
2. 更新index接入演示界面UI风格
3. 更新markdown文件预览UI风格
4. 更新XML文件预览UI风格调整类文本预览架构更方便扩展
5. 更新simTxT文件预览UI风格
6. 调整多图连续预览上下翻图的UI
7. 采用apache-common-io包简化所有的文件下载io操作
8. XML文件预览支持切换纯文本模式
9. 增强url base64解码失败时的提示信息
10. 修复导包错误以及图片预览 bug
11. 修复发行包运行时找不到日志目录的问题
12. 修复压缩包内多图连续预览的bug
13. 修复大小写文件类型后缀没通用匹配的问题
14. 指定Base64转码采用Apache Commons-code中的实现修复base64部分jdk版本下出现的异常
15. 修复类文本类型HTML文件预览的bug
16. 修复dwg文件预览时无法在jpg和pdf两种类型之间切换
17. escaping of dangerous characters to prevent reflected xss
18. 修复重复编码导致文档转图片预览失败的问题&编码规范
> 2020年12月27日
2020年年终大版本更新架构全面设计代码全面重构代码质量全面提升二次开发更便捷欢迎拉源码品鉴提issue、pr共同建设
1. 架构模块调整,大量的代码重构代码质量提升N个等级欢迎品鉴
2. 增强XML文件预览效果新增XML文档数结构预览
3. 新增markdown文件预览支持预览支持md渲染和源文本切换支持
4. 切换底层web server为jetty解决这个issuehttps://github.com/kekingcn/kkFileView/issues/168
5. 引入cpdetector解决文件编码识别问题
6. url采用base64+urlencode双编码彻底解决各种奇葩文件名预览问题
7. 新增配置项office.preview.switch.disabled控制offic文件预览切换开关
8. 优化文本类型文件预览逻辑采用Base64传输内容避免预览时再次请求文件内容
9. office预览图片模式禁用图片放大效果达到图片和pdf预览效果一致的体验
10. 直接代码静态设置pdfbox兼容低版本jdk在IDEA中运行也不会有警告提示
11. 移除guava、hutool等非必须的工具包减少代码体积
12. Office组件加载异步化提速应用启动速度最快到5秒内
13. 合理设置预览消费队列的线程数
14. 修复压缩包里文件再次预览失败的bug
15. 修复图片预览的bug
> 2020年05月20日
1. 新增支持全局水印,并支持通过参数动态改变水印内容
2. 新增支持CAD文件预览
3. 新增base.url配置支持使用nginx反向代理和使用context-path
4. 支持所有配置项支持从环境变量里读取方便Docker镜像部署和集群中大规模使用
5. 支持配置限信任站点(只能预览来自信任点的文件源),保护预览服务不被滥用
6. 支持配置自定义缓存清理时间cron表达式
7. 全部能识别的纯文本直接预览,不用再转跳下载,如.md .java .py等
8. 支持配置限制转换后的PDF文件下载
9. 优化maven打包配置解决 .sh 脚本可能出现换行符问题
10. 将前端所有CDN依赖放到本地方便没有外网连接的用户使用
11. 首页评论服务由搜狐畅言切换到Gitalk
12. 修复url中包含特殊字符可能会引起的预览异常
13. 修复转换文件队列addTask异常
14. 修复其他已经问题
15. 官网建设:[https://kkfileview.keking.cn](https://kkfileview.keking.cn)
16. 官方Docker镜像仓库建设[https://hub.docker.com/r/keking/kkfileview](https://hub.docker.com/r/keking/kkfileview)
> 2019年06月18日
1. 支持自动清理缓存及预览文件
2. 支持http/https下载流url文件预览
3. 支持FTP url文件预览
4. 加入Docker构建
> 2019年04月08日
1. 缓存及队列实现抽象提供JDK和REDIS两种实现(REDIS成为可选依赖)
2. 打包方式提供zip和tar.gz包并提供一键启动脚本
> 2018年01月19日
1. 大文件入队提前处理
1. 新增addTask文件转换入队接口
1. 采用redis队列支持kkFIleView接口和异构系统入队两种方式
> 2018年01月17日
1. 优化项目结构,抽象文件预览接口,更方便的加入更多的文件类型预览支持,方便二次开发
1. 新增英文文档说明(@幻幻Fate@汝辉)贡献
1. 新增图片预览文件支持类型
1. 修复压缩包内轮播图片总是从第一张开始的问题
> 2018年01月12日
1. 新增多图片同时预览
1. 支持压缩包内图片轮番预览
> 2018年01月02日
1. 修复txt等文本编码问题导致预览乱码
1. 修复项目模块依赖引入不到的问题
1. 新增spring boot profile支持多环境配置
1. 引入pdf.js预览doc等文件支持doc标题生成pdf预览菜单支持手机端预览
### 使用登记
如果这个项目解决了你的实际问题,可在 https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢
### Stars 趋势图
#### Gitee
[![Stargazers over time](https://whnb.wang/img/kekingcn/file-online-preview)](https://whnb.wang/kekingcn/file-online-preview?e=86400)
#### GitHub
[![Stargazers over time](https://starchart.cc/kekingcn/kkFileView.svg)](https://starchart.cc/kekingcn/kkFileView)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

11
index.js Normal file
View File

@ -0,0 +1,11 @@
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.set('Content-Type', 'text/plain');
res.send('Hello World');
});
module.exports = app.listen(8080, () => {
});

View File

@ -1,162 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>filepreview</artifactId>
<groupId>cn.keking</groupId>
<version>3.6.0</version>
</parent>
<artifactId>office-plugin</artifactId>
<repositories>
<repository>
<!-- required for org.hyperic:sigar -->
<id>jboss-public-repository-group</id>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>juh</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>ridl</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>unoil</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<!-- for the command line tool -->
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hyperic</groupId>
<artifactId>sigar</artifactId>
<version>1.6.5.132</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.0.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 要将源码放上去,需要加入这个插件 -->
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.1</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<configuration>
<!-- don't run tests in parallel -->
<perCoreThreadCount>false</perCoreThreadCount>
<threadCount>1</threadCount>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<mainClass>org.artofsolving.jodconverter.cli.Convert</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dist.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</reporting>
<!-- distribute目录 -->
<distributionManagement>
<repository>
<id>repo</id>
<name>User Project Releases</name>
<url>http://192.168.1.204:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>repo</id>
<name>User Project SNAPSHOTS</name>
<url>http://192.168.1.204:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>

View File

@ -1,37 +0,0 @@
<assembly>
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<excludes>
<exclude>org.hyperic:sigar</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<includes>
<include>LICENSE.txt</include>
<include>README.txt</include>
</includes>
</fileSet>
<fileSet>
<directory>target</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}-javadoc.jar</include>
<include>${project.artifactId}-${project.version}-sources.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>/conf</outputDirectory>
<includes>
<include>document-formats.js</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@ -1,125 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter;
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
import static org.artofsolving.jodconverter.office.OfficeUtils.toUnoProperties;
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
import java.io.File;
import java.util.Map;
import org.artofsolving.jodconverter.office.OfficeContext;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeTask;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.io.IOException;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.XComponent;
import com.sun.star.task.ErrorCodeIOException;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XCloseable;
public abstract class AbstractConversionTask implements OfficeTask {
private final File inputFile;
private final File outputFile;
public AbstractConversionTask(File inputFile, File outputFile) {
this.inputFile = inputFile;
this.outputFile = outputFile;
}
protected abstract Map<String,?> getLoadProperties(File inputFile);
protected abstract Map<String,?> getStoreProperties(File outputFile, XComponent document);
public void execute(OfficeContext context) throws OfficeException {
XComponent document = null;
try {
document = loadDocument(context, inputFile);
modifyDocument(document);
storeDocument(document, outputFile);
} catch (OfficeException officeException) {
throw officeException;
} catch (Exception exception) {
throw new OfficeException("conversion failed", exception);
} finally {
if (document != null) {
XCloseable closeable = cast(XCloseable.class, document);
if (closeable != null) {
try {
closeable.close(true);
} catch (CloseVetoException closeVetoException) {
// whoever raised the veto should close the document
}
} else {
document.dispose();
}
}
}
}
private XComponent loadDocument(OfficeContext context, File inputFile) throws OfficeException {
if (!inputFile.exists()) {
throw new OfficeException("input document not found");
}
XComponentLoader loader = cast(XComponentLoader.class, context.getService(SERVICE_DESKTOP));
Map<String,?> loadProperties = getLoadProperties(inputFile);
XComponent document = null;
try {
document = loader.loadComponentFromURL(toUrl(inputFile), "_blank", 0, toUnoProperties(loadProperties));
} catch (IllegalArgumentException illegalArgumentException) {
throw new OfficeException("could not load document: " + inputFile.getName(), illegalArgumentException);
} catch (ErrorCodeIOException errorCodeIOException) {
throw new OfficeException("could not load document: " + inputFile.getName() + "; errorCode: " + errorCodeIOException.ErrCode, errorCodeIOException);
} catch (IOException ioException) {
throw new OfficeException("could not load document: " + inputFile.getName(), ioException);
}
if (document == null) {
throw new OfficeException("could not load document: " + inputFile.getName());
}
return document;
}
/**
* Override to modify the document after it has been loaded and before it gets
* saved in the new format.
* <p>
* Does nothing by default.
*
* @param document
* @throws OfficeException
*/
protected void modifyDocument(XComponent document) throws OfficeException {
// noop
}
private void storeDocument(XComponent document, File outputFile) throws OfficeException {
Map<String,?> storeProperties = getStoreProperties(outputFile, document);
if (storeProperties == null) {
throw new OfficeException("unsupported conversion");
}
try {
cast(XStorable.class, document).storeToURL(toUrl(outputFile), toUnoProperties(storeProperties));
} catch (ErrorCodeIOException errorCodeIOException) {
throw new OfficeException("could not store document: " + outputFile.getName() + "; errorCode: " + errorCodeIOException.ErrCode, errorCodeIOException);
} catch (IOException ioException) {
throw new OfficeException("could not store document: " + outputFile.getName(), ioException);
}
}
}

View File

@ -1,75 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
import org.artofsolving.jodconverter.document.DocumentFormat;
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager;
import com.sun.star.document.UpdateDocMode;
public class OfficeDocumentConverter {
private final OfficeManager officeManager;
private final DocumentFormatRegistry formatRegistry;
private Map<String,?> defaultLoadProperties = createDefaultLoadProperties();
public OfficeDocumentConverter(OfficeManager officeManager) {
this(officeManager, new DefaultDocumentFormatRegistry());
}
public OfficeDocumentConverter(OfficeManager officeManager, DocumentFormatRegistry formatRegistry) {
this.officeManager = officeManager;
this.formatRegistry = formatRegistry;
}
private Map<String,Object> createDefaultLoadProperties() {
Map<String,Object> loadProperties = new HashMap<String,Object>();
loadProperties.put("Hidden", true);
loadProperties.put("ReadOnly", true);
loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE);
return loadProperties;
}
public void setDefaultLoadProperties(Map<String, ?> defaultLoadProperties) {
this.defaultLoadProperties = defaultLoadProperties;
}
public DocumentFormatRegistry getFormatRegistry() {
return formatRegistry;
}
public void convert(File inputFile, File outputFile) throws OfficeException {
String outputExtension = FilenameUtils.getExtension(outputFile.getName());
DocumentFormat outputFormat = formatRegistry.getFormatByExtension(outputExtension);
convert(inputFile, outputFile, outputFormat);
}
public void convert(File inputFile, File outputFile, DocumentFormat outputFormat) throws OfficeException {
String inputExtension = FilenameUtils.getExtension(inputFile.getName());
DocumentFormat inputFormat = formatRegistry.getFormatByExtension(inputExtension);
StandardConversionTask conversionTask = new StandardConversionTask(inputFile, outputFile, outputFormat);
conversionTask.setDefaultLoadProperties(defaultLoadProperties);
conversionTask.setInputFormat(inputFormat);
officeManager.execute(conversionTask);
}
}

View File

@ -1,47 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter;
import static org.artofsolving.jodconverter.office.OfficeUtils.*;
import org.artofsolving.jodconverter.document.DocumentFamily;
import org.artofsolving.jodconverter.office.OfficeException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XServiceInfo;
class OfficeDocumentUtils {
private OfficeDocumentUtils() {
throw new AssertionError("utility class must not be instantiated");
}
public static DocumentFamily getDocumentFamily(XComponent document) throws OfficeException {
XServiceInfo serviceInfo = cast(XServiceInfo.class, document);
if (serviceInfo.supportsService("com.sun.star.text.GenericTextDocument")) {
// NOTE: a GenericTextDocument is either a TextDocument, a WebDocument, or a GlobalDocument
// but this further distinction doesn't seem to matter for conversions
return DocumentFamily.TEXT;
} else if (serviceInfo.supportsService("com.sun.star.sheet.SpreadsheetDocument")) {
return DocumentFamily.SPREADSHEET;
} else if (serviceInfo.supportsService("com.sun.star.presentation.PresentationDocument")) {
return DocumentFamily.PRESENTATION;
} else if (serviceInfo.supportsService("com.sun.star.drawing.DrawingDocument")) {
return DocumentFamily.DRAWING;
} else {
throw new OfficeException("document of unknown family: " + serviceInfo.getImplementationName());
}
}
}

View File

@ -1,74 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter;
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.artofsolving.jodconverter.document.DocumentFamily;
import org.artofsolving.jodconverter.document.DocumentFormat;
import org.artofsolving.jodconverter.office.OfficeException;
import com.sun.star.lang.XComponent;
import com.sun.star.util.XRefreshable;
public class StandardConversionTask extends AbstractConversionTask {
private final DocumentFormat outputFormat;
private Map<String,?> defaultLoadProperties;
private DocumentFormat inputFormat;
public StandardConversionTask(File inputFile, File outputFile, DocumentFormat outputFormat) {
super(inputFile, outputFile);
this.outputFormat = outputFormat;
}
public void setDefaultLoadProperties(Map<String, ?> defaultLoadProperties) {
this.defaultLoadProperties = defaultLoadProperties;
}
public void setInputFormat(DocumentFormat inputFormat) {
this.inputFormat = inputFormat;
}
@Override
protected void modifyDocument(XComponent document) throws OfficeException {
XRefreshable refreshable = cast(XRefreshable.class, document);
if (refreshable != null) {
refreshable.refresh();
}
}
@Override
protected Map<String,?> getLoadProperties(File inputFile) {
Map<String,Object> loadProperties = new HashMap<String,Object>();
if (defaultLoadProperties != null) {
loadProperties.putAll(defaultLoadProperties);
}
if (inputFormat != null && inputFormat.getLoadProperties() != null) {
loadProperties.putAll(inputFormat.getLoadProperties());
}
return loadProperties;
}
@Override
protected Map<String,?> getStoreProperties(File outputFile, XComponent document) {
DocumentFamily family = OfficeDocumentUtils.getDocumentFamily(document);
return outputFormat.getStoreProperties(family);
}
}

View File

@ -1,126 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.cli;
import java.io.File;
import java.io.IOException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
import org.artofsolving.jodconverter.document.JsonDocumentFormatRegistry;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.json.JSONException;
/**
* Command line interface executable.
*/
public class Convert {
public static final int STATUS_OK = 0;
public static final int STATUS_MISSING_INPUT_FILE = 1;
public static final int STATUS_INVALID_ARGUMENTS = 255;
private static final Option OPTION_OUTPUT_FORMAT = new Option("o", "output-format", true, "output format (e.g. pdf)");
private static final Option OPTION_PORT = new Option("p", "port", true, "office socket port (optional; defaults to 2002)");
private static final Option OPTION_REGISTRY = new Option("r", "registry", true, "document formats registry configuration file (optional)");
private static final Option OPTION_TIMEOUT = new Option("t", "timeout", true, "maximum conversion time in seconds (optional; defaults to 120)");
private static final Option OPTION_USER_PROFILE = new Option("u", "user-profile", true, "use settings from the given user installation dir (optional)");
private static final Options OPTIONS = initOptions();
private static final int DEFAULT_OFFICE_PORT = 2002;
private static Options initOptions() {
Options options = new Options();
options.addOption(OPTION_OUTPUT_FORMAT);
options.addOption(OPTION_PORT);
options.addOption(OPTION_REGISTRY);
options.addOption(OPTION_TIMEOUT);
options.addOption(OPTION_USER_PROFILE);
return options;
}
public static void main(String[] arguments) throws ParseException, JSONException, IOException {
CommandLineParser commandLineParser = new PosixParser();
CommandLine commandLine = commandLineParser.parse(OPTIONS, arguments);
String outputFormat = null;
if (commandLine.hasOption(OPTION_OUTPUT_FORMAT.getOpt())) {
outputFormat = commandLine.getOptionValue(OPTION_OUTPUT_FORMAT.getOpt());
}
int port = DEFAULT_OFFICE_PORT;
if (commandLine.hasOption(OPTION_PORT.getOpt())) {
port = Integer.parseInt(commandLine.getOptionValue(OPTION_PORT.getOpt()));
}
String[] fileNames = commandLine.getArgs();
if ((outputFormat == null && fileNames.length != 2) || fileNames.length < 1) {
String syntax = "java -jar jodconverter-core.jar [options] input-file output-file\n"
+ "or [options] -o output-format input-file [input-file...]";
HelpFormatter helpFormatter = new HelpFormatter();
helpFormatter.printHelp(syntax, OPTIONS);
System.exit(STATUS_INVALID_ARGUMENTS);
}
DocumentFormatRegistry registry;
if (commandLine.hasOption(OPTION_REGISTRY.getOpt())) {
File registryFile = new File(commandLine.getOptionValue(OPTION_REGISTRY.getOpt()));
registry = new JsonDocumentFormatRegistry(FileUtils.readFileToString(registryFile));
} else {
registry = new DefaultDocumentFormatRegistry();
}
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
configuration.setPortNumber(port);
if (commandLine.hasOption(OPTION_TIMEOUT.getOpt())) {
int timeout = Integer.parseInt(commandLine.getOptionValue(OPTION_TIMEOUT.getOpt()));
configuration.setTaskExecutionTimeout(timeout * 1000);
}
if (commandLine.hasOption(OPTION_USER_PROFILE.getOpt())) {
String templateProfileDir = commandLine.getOptionValue(OPTION_USER_PROFILE.getOpt());
configuration.setTemplateProfileDir(new File(templateProfileDir));
}
OfficeManager officeManager = configuration.buildOfficeManager();
officeManager.start();
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, registry);
try {
if (outputFormat == null) {
File inputFile = new File(fileNames[0]);
File outputFile = new File(fileNames[1]);
converter.convert(inputFile, outputFile);
} else {
for (int i = 0; i < fileNames.length; i++) {
File inputFile = new File(fileNames[i]);
String outputName = FilenameUtils.getBaseName(fileNames[i]) + "." + outputFormat;
File outputFile = new File(FilenameUtils.getFullPath(fileNames[i]) + outputName);
converter.convert(inputFile, outputFile);
}
}
} finally {
officeManager.stop();
}
}
}

View File

@ -1,157 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
public class DefaultDocumentFormatRegistry extends SimpleDocumentFormatRegistry {
public DefaultDocumentFormatRegistry() {
DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf");
pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_pdf_Export"));
addFormat(pdf);
DocumentFormat swf = new DocumentFormat("Macromedia Flash", "swf", "application/x-shockwave-flash");
swf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_flash_Export"));
swf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_flash_Export"));
addFormat(swf);
// disabled because it's not always available
//DocumentFormat xhtml = new DocumentFormat("XHTML", "xhtml", "application/xhtml+xml");
//xhtml.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "XHTML Writer File"));
//xhtml.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "XHTML Calc File"));
//xhtml.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "XHTML Impress File"));
//addFormat(xhtml);
DocumentFormat html = new DocumentFormat("HTML", "html", "text/html");
// HTML is treated as Text when supplied as input, but as an output it is also
// available for exporting Spreadsheet and Presentation formats
html.setInputFamily(DocumentFamily.TEXT);
html.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "HTML (StarWriter)"));
html.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "HTML (StarCalc)"));
html.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_html_Export"));
addFormat(html);
DocumentFormat odt = new DocumentFormat("OpenDocument Text", "odt", "application/vnd.oasis.opendocument.text");
odt.setInputFamily(DocumentFamily.TEXT);
odt.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer8"));
addFormat(odt);
DocumentFormat sxw = new DocumentFormat("OpenOffice.org 1.0 Text Document", "sxw", "application/vnd.sun.xml.writer");
sxw.setInputFamily(DocumentFamily.TEXT);
sxw.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "StarOffice XML (Writer)"));
addFormat(sxw);
DocumentFormat doc = new DocumentFormat("Microsoft Word", "doc", "application/msword");
doc.setInputFamily(DocumentFamily.TEXT);
doc.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MS Word 97"));
addFormat(doc);
DocumentFormat docx = new DocumentFormat("Microsoft Word 2007 XML", "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
docx.setInputFamily(DocumentFamily.TEXT);
addFormat(docx);
DocumentFormat rtf = new DocumentFormat("Rich Text Format", "rtf", "text/rtf");
rtf.setInputFamily(DocumentFamily.TEXT);
rtf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "Rich Text Format"));
addFormat(rtf);
DocumentFormat wpd = new DocumentFormat("WordPerfect", "wpd", "application/wordperfect");
wpd.setInputFamily(DocumentFamily.TEXT);
addFormat(wpd);
DocumentFormat txt = new DocumentFormat("Plain Text", "txt", "text/plain");
txt.setInputFamily(DocumentFamily.TEXT);
Map<String,Object> txtLoadAndStoreProperties = new LinkedHashMap<String,Object>();
txtLoadAndStoreProperties.put("FilterName", "Text (encoded)");
txtLoadAndStoreProperties.put("FilterOptions", "utf8");
txt.setLoadProperties(txtLoadAndStoreProperties);
txt.setStoreProperties(DocumentFamily.TEXT, txtLoadAndStoreProperties);
addFormat(txt);
DocumentFormat wikitext = new DocumentFormat("MediaWiki wikitext", "wiki", "text/x-wiki");
wikitext.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MediaWiki"));
//addFormat(wikitext);
DocumentFormat ods = new DocumentFormat("OpenDocument Spreadsheet", "ods", "application/vnd.oasis.opendocument.spreadsheet");
ods.setInputFamily(DocumentFamily.SPREADSHEET);
ods.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc8"));
addFormat(ods);
DocumentFormat sxc = new DocumentFormat("OpenOffice.org 1.0 Spreadsheet", "sxc", "application/vnd.sun.xml.calc");
sxc.setInputFamily(DocumentFamily.SPREADSHEET);
sxc.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "StarOffice XML (Calc)"));
addFormat(sxc);
DocumentFormat xls = new DocumentFormat("Microsoft Excel", "xls", "application/vnd.ms-excel");
xls.setInputFamily(DocumentFamily.SPREADSHEET);
xls.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "MS Excel 97"));
addFormat(xls);
DocumentFormat xlsx = new DocumentFormat("Microsoft Excel 2007 XML", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
xlsx.setInputFamily(DocumentFamily.SPREADSHEET);
addFormat(xlsx);
DocumentFormat csv = new DocumentFormat("Comma Separated Values", "csv", "text/csv");
csv.setInputFamily(DocumentFamily.SPREADSHEET);
Map<String,Object> csvLoadAndStoreProperties = new LinkedHashMap<String,Object>();
csvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
csvLoadAndStoreProperties.put("FilterOptions", "44,34,0"); // Field Separator: ','; Text Delimiter: '"'
csv.setLoadProperties(csvLoadAndStoreProperties);
csv.setStoreProperties(DocumentFamily.SPREADSHEET, csvLoadAndStoreProperties);
addFormat(csv);
DocumentFormat tsv = new DocumentFormat("Tab Separated Values", "tsv", "text/tab-separated-values");
tsv.setInputFamily(DocumentFamily.SPREADSHEET);
Map<String,Object> tsvLoadAndStoreProperties = new LinkedHashMap<String,Object>();
tsvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
tsvLoadAndStoreProperties.put("FilterOptions", "9,34,0"); // Field Separator: '\t'; Text Delimiter: '"'
tsv.setLoadProperties(tsvLoadAndStoreProperties);
tsv.setStoreProperties(DocumentFamily.SPREADSHEET, tsvLoadAndStoreProperties);
addFormat(tsv);
DocumentFormat odp = new DocumentFormat("OpenDocument Presentation", "odp", "application/vnd.oasis.opendocument.presentation");
odp.setInputFamily(DocumentFamily.PRESENTATION);
odp.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress8"));
addFormat(odp);
DocumentFormat sxi = new DocumentFormat("OpenOffice.org 1.0 Presentation", "sxi", "application/vnd.sun.xml.impress");
sxi.setInputFamily(DocumentFamily.PRESENTATION);
sxi.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "StarOffice XML (Impress)"));
addFormat(sxi);
DocumentFormat ppt = new DocumentFormat("Microsoft PowerPoint", "ppt", "application/vnd.ms-powerpoint");
ppt.setInputFamily(DocumentFamily.PRESENTATION);
ppt.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "MS PowerPoint 97"));
addFormat(ppt);
DocumentFormat pptx = new DocumentFormat("Microsoft PowerPoint 2007 XML", "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
pptx.setInputFamily(DocumentFamily.PRESENTATION);
addFormat(pptx);
DocumentFormat odg = new DocumentFormat("OpenDocument Drawing", "odg", "application/vnd.oasis.opendocument.graphics");
odg.setInputFamily(DocumentFamily.DRAWING);
odg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw8"));
addFormat(odg);
DocumentFormat svg = new DocumentFormat("Scalable Vector Graphics", "svg", "image/svg+xml");
svg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_svg_Export"));
addFormat(svg);
}
}

View File

@ -1,19 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
public enum DocumentFamily {
TEXT, SPREADSHEET, PRESENTATION, DRAWING
}

View File

@ -1,99 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
import java.util.HashMap;
import java.util.Map;
public class DocumentFormat {
private String name;
private String extension;
private String mediaType;
private DocumentFamily inputFamily;
private Map<String,?> loadProperties;
private Map<DocumentFamily,Map<String,?>> storePropertiesByFamily;
public DocumentFormat() {
// default
}
public DocumentFormat(String name, String extension, String mediaType) {
this.name = name;
this.extension = extension;
this.mediaType = mediaType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getMediaType() {
return mediaType;
}
public void setMediaType(String mediaType) {
this.mediaType = mediaType;
}
public DocumentFamily getInputFamily() {
return inputFamily;
}
public void setInputFamily(DocumentFamily documentFamily) {
this.inputFamily = documentFamily;
}
public Map<String, ?> getLoadProperties() {
return loadProperties;
}
public void setLoadProperties(Map<String,?> loadProperties) {
this.loadProperties = loadProperties;
}
public Map<DocumentFamily, Map<String, ?>> getStorePropertiesByFamily() {
return storePropertiesByFamily;
}
public void setStorePropertiesByFamily(Map<DocumentFamily, Map<String,?>> storePropertiesByFamily) {
this.storePropertiesByFamily = storePropertiesByFamily;
}
public void setStoreProperties(DocumentFamily family, Map<String,?> storeProperties) {
if (storePropertiesByFamily == null) {
storePropertiesByFamily = new HashMap<DocumentFamily,Map<String,?>>();
}
storePropertiesByFamily.put(family, storeProperties);
}
public Map<String,?> getStoreProperties(DocumentFamily family) {
if (storePropertiesByFamily == null) {
return null;
}
return storePropertiesByFamily.get(family);
}
}

View File

@ -1,25 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
import java.util.Set;
public interface DocumentFormatRegistry {
public DocumentFormat getFormatByExtension(String extension);
public DocumentFormat getFormatByMediaType(String mediaType);
public Set<DocumentFormat> getOutputFormats(DocumentFamily family);
}

View File

@ -1,73 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class JsonDocumentFormatRegistry extends SimpleDocumentFormatRegistry {
public JsonDocumentFormatRegistry(InputStream input) throws JSONException, IOException {
readJsonArray(IOUtils.toString(input));
}
public JsonDocumentFormatRegistry(String source) throws JSONException {
readJsonArray(source);
}
private void readJsonArray(String source) throws JSONException {
JSONArray array = new JSONArray(source);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonFormat = array.getJSONObject(i);
DocumentFormat format = new DocumentFormat();
format.setName(jsonFormat.getString("name"));
format.setExtension(jsonFormat.getString("extension"));
format.setMediaType(jsonFormat.getString("mediaType"));
if (jsonFormat.has("inputFamily")) {
format.setInputFamily(DocumentFamily.valueOf(jsonFormat.getString("inputFamily")));
}
if (jsonFormat.has("loadProperties")) {
format.setLoadProperties(toJavaMap(jsonFormat.getJSONObject("loadProperties")));
}
if (jsonFormat.has("storePropertiesByFamily")) {
JSONObject jsonStorePropertiesByFamily = jsonFormat.getJSONObject("storePropertiesByFamily");
for (String key : JSONObject.getNames(jsonStorePropertiesByFamily)) {
Map<String,?> storeProperties = toJavaMap(jsonStorePropertiesByFamily.getJSONObject(key));
format.setStoreProperties(DocumentFamily.valueOf(key), storeProperties);
}
}
addFormat(format);
}
}
private Map<String,?> toJavaMap(JSONObject jsonMap) throws JSONException {
Map<String,Object> map = new HashMap<String,Object>();
for (String key : JSONObject.getNames(jsonMap)) {
Object value = jsonMap.get(key);
if (value instanceof JSONObject) {
map.put(key, toJavaMap((JSONObject) value));
} else {
map.put(key, value);
}
}
return map;
}
}

View File

@ -1,65 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.document;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SimpleDocumentFormatRegistry implements DocumentFormatRegistry {
private List<DocumentFormat> documentFormats = new ArrayList<DocumentFormat>();
public void addFormat(DocumentFormat documentFormat) {
documentFormats.add(documentFormat);
}
public DocumentFormat getFormatByExtension(String extension) {
if (extension == null) {
return null;
}
String lowerExtension = extension.toLowerCase();
//TODO keep a documentByExtension map instead
for (DocumentFormat format : documentFormats) {
if (format.getExtension().equals(lowerExtension)) {
return format;
}
}
return null;
}
public DocumentFormat getFormatByMediaType(String mediaType) {
if (mediaType == null) {
return null;
}
//TODO keep a documentByMediaType map instead
for (DocumentFormat format : documentFormats) {
if (format.getMediaType().equals(mediaType)) {
return format;
}
}
return null;
}
public Set<DocumentFormat> getOutputFormats(DocumentFamily family) {
Set<DocumentFormat> formats = new HashSet<DocumentFormat>();
for (DocumentFormat format : documentFormats) {
if (format.getStoreProperties(family) != null) {
formats.add(format);
}
}
return formats;
}
}

View File

@ -1,223 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.io.File;
import org.artofsolving.jodconverter.process.ProcessManager;
import org.artofsolving.jodconverter.process.PureJavaProcessManager;
import org.artofsolving.jodconverter.process.LinuxProcessManager;
import org.artofsolving.jodconverter.process.SigarProcessManager;
import org.artofsolving.jodconverter.util.PlatformUtils;
public class DefaultOfficeManagerConfiguration {
public static final long DEFAULT_RETRY_TIMEOUT = 120000L;
private File officeHome = OfficeUtils.getDefaultOfficeHome();
private OfficeConnectionProtocol connectionProtocol = OfficeConnectionProtocol.SOCKET;
private int[] portNumbers = new int[] { 2002 };
private String[] pipeNames = new String[] { "office" };
private String[] runAsArgs = null;
private File templateProfileDir = null;
private File workDir = new File(System.getProperty("java.io.tmpdir"));
private long taskQueueTimeout = 30000L; // 30 seconds
private long taskExecutionTimeout = 120000L; // 2 minutes
private int maxTasksPerProcess = 200;
private long retryTimeout = DEFAULT_RETRY_TIMEOUT;
private ProcessManager processManager = null; // lazily initialised
public DefaultOfficeManagerConfiguration setOfficeHome(String officeHome) throws NullPointerException, IllegalArgumentException {
checkArgumentNotNull("officeHome", officeHome);
return setOfficeHome(new File(officeHome));
}
public DefaultOfficeManagerConfiguration setOfficeHome(File officeHome) throws NullPointerException, IllegalArgumentException {
checkArgumentNotNull("officeHome", officeHome);
checkArgument("officeHome", officeHome.isDirectory(), "must exist and be a directory");
this.officeHome = officeHome;
return this;
}
public DefaultOfficeManagerConfiguration setConnectionProtocol(OfficeConnectionProtocol connectionProtocol) throws NullPointerException {
checkArgumentNotNull("connectionProtocol", connectionProtocol);
this.connectionProtocol = connectionProtocol;
return this;
}
public DefaultOfficeManagerConfiguration setPortNumber(int portNumber) {
this.portNumbers = new int[] { portNumber };
return this;
}
public DefaultOfficeManagerConfiguration setPortNumbers(int... portNumbers) throws NullPointerException, IllegalArgumentException {
checkArgumentNotNull("portNumbers", portNumbers);
checkArgument("portNumbers", portNumbers.length > 0, "must not be empty");
this.portNumbers = portNumbers;
return this;
}
public DefaultOfficeManagerConfiguration setPipeName(String pipeName) throws NullPointerException {
checkArgumentNotNull("pipeName", pipeName);
this.pipeNames = new String[] { pipeName };
return this;
}
public DefaultOfficeManagerConfiguration setPipeNames(String... pipeNames) throws NullPointerException, IllegalArgumentException {
checkArgumentNotNull("pipeNames", pipeNames);
checkArgument("pipeNames", pipeNames.length > 0, "must not be empty");
this.pipeNames = pipeNames;
return this;
}
public DefaultOfficeManagerConfiguration setRunAsArgs(String... runAsArgs) {
this.runAsArgs = runAsArgs;
return this;
}
public DefaultOfficeManagerConfiguration setTemplateProfileDir(File templateProfileDir) throws IllegalArgumentException {
if (templateProfileDir != null) {
checkArgument("templateProfileDir", templateProfileDir.isDirectory(), "must exist and be a directory");
}
this.templateProfileDir = templateProfileDir;
return this;
}
/**
* Sets the directory where temporary office profiles will be created.
* <p>
* Defaults to the system temporary directory as specified by the <code>java.io.tmpdir</code> system property.
*
* @param workDir
* @return
*/
public DefaultOfficeManagerConfiguration setWorkDir(File workDir) {
checkArgumentNotNull("workDir", workDir);
this.workDir = workDir;
return this;
}
public DefaultOfficeManagerConfiguration setTaskQueueTimeout(long taskQueueTimeout) {
this.taskQueueTimeout = taskQueueTimeout;
return this;
}
public DefaultOfficeManagerConfiguration setTaskExecutionTimeout(long taskExecutionTimeout) {
this.taskExecutionTimeout = taskExecutionTimeout;
return this;
}
public DefaultOfficeManagerConfiguration setMaxTasksPerProcess(int maxTasksPerProcess) {
this.maxTasksPerProcess = maxTasksPerProcess;
return this;
}
/**
* Provide a specific {@link ProcessManager} implementation
* <p>
* The default is to use {@link SigarProcessManager} if sigar.jar is
* available in the classpath, otherwise {@link LinuxProcessManager}
* on Linux and {@link PureJavaProcessManager} on other platforms.
*
* @param processManager
* @return
* @throws NullPointerException
*/
public DefaultOfficeManagerConfiguration setProcessManager(ProcessManager processManager) throws NullPointerException {
checkArgumentNotNull("processManager", processManager);
this.processManager = processManager;
return this;
}
/**
* Retry timeout set in milliseconds. Used for retrying office process calls.
* If not set, it defaults to 2 minutes
*
* @param retryTimeout in milliseconds
* @return
*/
public DefaultOfficeManagerConfiguration setRetryTimeout(long retryTimeout) {
this.retryTimeout = retryTimeout;
return this;
}
public OfficeManager buildOfficeManager() throws IllegalStateException {
if (officeHome == null) {
throw new IllegalStateException("officeHome not set and could not be auto-detected");
} else if (!officeHome.isDirectory()) {
throw new IllegalStateException("officeHome doesn't exist or is not a directory: " + officeHome);
} else if (!OfficeUtils.getOfficeExecutable(officeHome).isFile()) {
throw new IllegalStateException("invalid officeHome: it doesn't contain soffice.bin: " + officeHome);
}
if (templateProfileDir != null && !isValidProfileDir(templateProfileDir)) {
throw new IllegalStateException("templateProfileDir doesn't appear to contain a user profile: " + templateProfileDir);
}
if (!workDir.isDirectory()) {
throw new IllegalStateException("workDir doesn't exist or is not a directory: " + workDir);
}
if (processManager == null) {
processManager = findBestProcessManager();
}
int numInstances = connectionProtocol == OfficeConnectionProtocol.PIPE ? pipeNames.length : portNumbers.length;
UnoUrl[] unoUrls = new UnoUrl[numInstances];
for (int i = 0; i < numInstances; i++) {
unoUrls[i] = (connectionProtocol == OfficeConnectionProtocol.PIPE) ? UnoUrl.pipe(pipeNames[i]) : UnoUrl.socket(portNumbers[i]);
}
return new ProcessPoolOfficeManager(officeHome, unoUrls, runAsArgs, templateProfileDir, workDir, retryTimeout, taskQueueTimeout, taskExecutionTimeout, maxTasksPerProcess, processManager);
}
private ProcessManager findBestProcessManager() {
if (isSigarAvailable()) {
return new SigarProcessManager();
} else if (PlatformUtils.isLinux()) {
LinuxProcessManager processManager = new LinuxProcessManager();
if (runAsArgs != null) {
processManager.setRunAsArgs(runAsArgs);
}
return processManager;
} else {
// NOTE: UnixProcessManager can't be trusted to work on Solaris
// because of the 80-char limit on ps output there
return new PureJavaProcessManager();
}
}
private boolean isSigarAvailable() {
try {
Class.forName("org.hyperic.sigar.Sigar", false, getClass().getClassLoader());
return true;
} catch (ClassNotFoundException classNotFoundException) {
return false;
}
}
private void checkArgumentNotNull(String argName, Object argValue) throws NullPointerException {
if (argValue == null) {
throw new NullPointerException(argName + " must not be null");
}
}
private void checkArgument(String argName, boolean condition, String message) throws IllegalArgumentException {
if (!condition) {
throw new IllegalArgumentException(argName + " " + message);
}
}
private boolean isValidProfileDir(File profileDir) {
return new File(profileDir, "user").isDirectory();
}
}

View File

@ -1,86 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.net.ConnectException;
/**
* {@link OfficeManager} implementation that connects to an external Office process.
* <p>
* The external Office process needs to be started manually, e.g. from the command line with
*
* <pre>
* soffice -accept="socket,host=127.0.0.1,port=2002;urp;"
* </pre>
* <p>
* Since this implementation does not manage the Office process, it does not support auto-restarting the process if it exits unexpectedly.
* <p>
* It will however auto-reconnect to the external process if the latter is manually restarted.
* <p>
* This {@link OfficeManager} implementation basically provides the same behaviour as JODConverter 2.x, including using <em>synchronized</em> blocks for serialising office
* operations.
*/
class ExternalOfficeManager implements OfficeManager {
private final OfficeConnection connection;
private final boolean connectOnStart;
/**
* @param unoUrl
* @param connectOnStart
* should a connection be attempted on {@link #start()}? Default is <em>true</em>. If <em>false</em>, a connection will only be attempted the first time an
* {@link OfficeTask} is executed.
*/
public ExternalOfficeManager(UnoUrl unoUrl, boolean connectOnStart) {
connection = new OfficeConnection(unoUrl);
this.connectOnStart = connectOnStart;
}
public void start() throws OfficeException {
if (connectOnStart) {
synchronized (connection) {
connect();
}
}
}
public void stop() {
synchronized (connection) {
if (connection.isConnected()) {
connection.disconnect();
}
}
}
public void execute(OfficeTask task) throws OfficeException {
synchronized (connection) {
if (!connection.isConnected()) {
connect();
}
task.execute(connection);
}
}
private void connect() {
try {
connection.connect();
} catch (ConnectException connectException) {
throw new OfficeException("could not connect to external office process", connectException);
}
}
public boolean isRunning() {
return connection.isConnected();
}
}

View File

@ -1,47 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
public class ExternalOfficeManagerConfiguration {
private OfficeConnectionProtocol connectionProtocol = OfficeConnectionProtocol.SOCKET;
private int portNumber = 2002;
private String pipeName = "office";
private boolean connectOnStart = true;
public ExternalOfficeManagerConfiguration setConnectionProtocol(OfficeConnectionProtocol connectionProtocol) {
this.connectionProtocol = connectionProtocol;
return this;
}
public ExternalOfficeManagerConfiguration setPortNumber(int portNumber) {
this.portNumber = portNumber;
return this;
}
public ExternalOfficeManagerConfiguration setPipeName(String pipeName) {
this.pipeName = pipeName;
return this;
}
public ExternalOfficeManagerConfiguration setConnectOnStart(boolean connectOnStart) {
this.connectOnStart = connectOnStart;
return this;
}
public OfficeManager buildOfficeManager() {
UnoUrl unoUrl = connectionProtocol == OfficeConnectionProtocol.SOCKET ? UnoUrl.socket(portNumber) : UnoUrl.pipe(pipeName);
return new ExternalOfficeManager(unoUrl, connectOnStart);
}
}

View File

@ -1,176 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.net.ConnectException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.DisposedException;
class ManagedOfficeProcess {
private static final Integer EXIT_CODE_NEW_INSTALLATION = Integer.valueOf(81);
private final ManagedOfficeProcessSettings settings;
private final OfficeProcess process;
private final OfficeConnection connection;
private ExecutorService executor = Executors.newSingleThreadExecutor(new NamedThreadFactory("OfficeProcessThread"));
private final Logger logger = Logger.getLogger(getClass().getName());
public ManagedOfficeProcess(ManagedOfficeProcessSettings settings) throws OfficeException {
this.settings = settings;
process = new OfficeProcess(settings.getOfficeHome(), settings.getUnoUrl(), settings.getRunAsArgs(), settings.getTemplateProfileDir(), settings.getWorkDir(), settings
.getProcessManager());
connection = new OfficeConnection(settings.getUnoUrl());
}
public OfficeConnection getConnection() {
return connection;
}
public void startAndWait() throws OfficeException {
Future<?> future = executor.submit(new Runnable() {
public void run() {
doStartProcessAndConnect();
}
});
try {
future.get();
} catch (Exception exception) {
throw new OfficeException("failed to start and connect", exception);
}
}
public void stopAndWait() throws OfficeException {
Future<?> future = executor.submit(new Runnable() {
public void run() {
doStopProcess();
}
});
try {
future.get();
} catch (Exception exception) {
throw new OfficeException("failed to start and connect", exception);
}
}
public void restartAndWait() {
Future<?> future = executor.submit(new Runnable() {
public void run() {
doStopProcess();
doStartProcessAndConnect();
}
});
try {
future.get();
} catch (Exception exception) {
throw new OfficeException("failed to restart", exception);
}
}
public void restartDueToTaskTimeout() {
executor.execute(new Runnable() {
public void run() {
doTerminateProcess();
// will cause unexpected disconnection and subsequent restart
}
});
}
public void restartDueToLostConnection() {
executor.execute(new Runnable() {
public void run() {
try {
doEnsureProcessExited();
doStartProcessAndConnect();
} catch (OfficeException officeException) {
logger.log(Level.SEVERE, "could not restart process", officeException);
}
}
});
}
private void doStartProcessAndConnect() throws OfficeException {
try {
process.start();
new Retryable() {
protected void attempt() throws TemporaryException, Exception {
try {
connection.connect();
} catch (ConnectException connectException) {
Integer exitCode = process.getExitCode();
if (exitCode == null) {
// process is running; retry later
throw new TemporaryException(connectException);
} else if (exitCode.equals(EXIT_CODE_NEW_INSTALLATION)) {
// restart and retry later
// see http://code.google.com/p/jodconverter/issues/detail?id=84
logger.log(Level.WARNING, "office process died with exit code 81; restarting it");
process.start(true);
throw new TemporaryException(connectException);
} else {
throw new OfficeException("office process died with exit code " + exitCode);
}
}
}
}.execute(settings.getRetryInterval(), settings.getRetryTimeout());
} catch (Exception exception) {
throw new OfficeException("could not establish connection", exception);
}
}
private void doStopProcess() {
try {
XDesktop desktop = OfficeUtils.cast(XDesktop.class, connection.getService(OfficeUtils.SERVICE_DESKTOP));
desktop.terminate();
} catch (DisposedException disposedException) {
// expected
} catch (Exception exception) {
// in case we can't get hold of the desktop
doTerminateProcess();
}
doEnsureProcessExited();
}
private void doEnsureProcessExited() throws OfficeException {
try {
int exitCode = process.getExitCode(settings.getRetryInterval(), settings.getRetryTimeout());
logger.info("process exited with code " + exitCode);
} catch (RetryTimeoutException retryTimeoutException) {
doTerminateProcess();
}
process.deleteProfileDir();
}
private void doTerminateProcess() throws OfficeException {
try {
int exitCode = process.forciblyTerminate(settings.getRetryInterval(), settings.getRetryTimeout());
logger.info("process forcibly terminated with code " + exitCode);
} catch (Exception exception) {
throw new OfficeException("could not terminate process", exception);
}
}
boolean isConnected() {
return connection.isConnected();
}
}

View File

@ -1,97 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.io.File;
import org.artofsolving.jodconverter.process.ProcessManager;
import org.artofsolving.jodconverter.process.PureJavaProcessManager;
class ManagedOfficeProcessSettings {
public static final long DEFAULT_RETRY_INTERVAL = 250L;
private final UnoUrl unoUrl;
private File officeHome = OfficeUtils.getDefaultOfficeHome();
private String[] runAsArgs;
private File templateProfileDir;
private File workDir = new File(System.getProperty("java.io.tmpdir"));
private ProcessManager processManager = new PureJavaProcessManager();
private long retryTimeout = DefaultOfficeManagerConfiguration.DEFAULT_RETRY_TIMEOUT;
private long retryInterval = DEFAULT_RETRY_INTERVAL;
public ManagedOfficeProcessSettings(UnoUrl unoUrl) {
this.unoUrl = unoUrl;
}
public UnoUrl getUnoUrl() {
return unoUrl;
}
public File getOfficeHome() {
return officeHome;
}
public void setOfficeHome(File officeHome) {
this.officeHome = officeHome;
}
public String[] getRunAsArgs() {
return runAsArgs;
}
public void setRunAsArgs(String[] runAsArgs) {
this.runAsArgs = runAsArgs;
}
public File getTemplateProfileDir() {
return templateProfileDir;
}
public void setTemplateProfileDir(File templateProfileDir) {
this.templateProfileDir = templateProfileDir;
}
public File getWorkDir() {
return workDir;
}
public void setWorkDir(File workDir) {
this.workDir = workDir;
}
public ProcessManager getProcessManager() {
return processManager;
}
public void setProcessManager(ProcessManager processManager) {
this.processManager = processManager;
}
public long getRetryTimeout() {
return retryTimeout;
}
public void setRetryTimeout(long retryTimeout) {
this.retryTimeout = retryTimeout;
}
public long getRetryInterval() {
return retryInterval;
}
public void setRetryInterval(long retryInterval) {
this.retryInterval = retryInterval;
}
}

View File

@ -1,43 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* A {@link ThreadFactory} that allows for custom thread names
*/
class NamedThreadFactory implements ThreadFactory {
private static final AtomicInteger threadIndex = new AtomicInteger(0);
private final String baseName;
private final boolean daemon;
public NamedThreadFactory(String baseName) {
this(baseName, true);
}
public NamedThreadFactory(String baseName, boolean daemon) {
this.baseName = baseName;
this.daemon = daemon;
}
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, baseName + "-" + threadIndex.getAndIncrement());
thread.setDaemon(daemon);
return thread;
}
}

View File

@ -1,117 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XBridgeFactory;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.connection.NoConnectException;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.lang.EventObject;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XEventListener;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
class OfficeConnection implements OfficeContext {
private static AtomicInteger bridgeIndex = new AtomicInteger();
private final UnoUrl unoUrl;
private XComponent bridgeComponent;
private XMultiComponentFactory serviceManager;
private XComponentContext componentContext;
private final List<OfficeConnectionEventListener> connectionEventListeners = new ArrayList<OfficeConnectionEventListener>();
private volatile boolean connected = false;
private XEventListener bridgeListener = new XEventListener() {
public void disposing(EventObject event) {
if (connected) {
connected = false;
logger.info(String.format("disconnected: '%s'", unoUrl));
OfficeConnectionEvent connectionEvent = new OfficeConnectionEvent(OfficeConnection.this);
for (OfficeConnectionEventListener listener : connectionEventListeners) {
listener.disconnected(connectionEvent);
}
}
// else we tried to connect to a server that doesn't speak URP
}
};
private final Logger logger = Logger.getLogger(getClass().getName());
public OfficeConnection(UnoUrl unoUrl) {
this.unoUrl = unoUrl;
}
public void addConnectionEventListener(OfficeConnectionEventListener connectionEventListener) {
connectionEventListeners.add(connectionEventListener);
}
public void connect() throws ConnectException {
logger.fine(String.format("connecting with connectString '%s'", unoUrl));
try {
XComponentContext localContext = Bootstrap.createInitialComponentContext(null);
XMultiComponentFactory localServiceManager = localContext.getServiceManager();
XConnector connector = OfficeUtils.cast(XConnector.class, localServiceManager.createInstanceWithContext("com.sun.star.connection.Connector", localContext));
XConnection connection = connector.connect(unoUrl.getConnectString());
XBridgeFactory bridgeFactory = OfficeUtils.cast(XBridgeFactory.class, localServiceManager.createInstanceWithContext("com.sun.star.bridge.BridgeFactory", localContext));
String bridgeName = "jodconverter_" + bridgeIndex.getAndIncrement();
XBridge bridge = bridgeFactory.createBridge(bridgeName, "urp", connection, null);
bridgeComponent = OfficeUtils.cast(XComponent.class, bridge);
bridgeComponent.addEventListener(bridgeListener);
serviceManager = OfficeUtils.cast(XMultiComponentFactory.class, bridge.getInstance("StarOffice.ServiceManager"));
XPropertySet properties = OfficeUtils.cast(XPropertySet.class, serviceManager);
componentContext = OfficeUtils.cast(XComponentContext.class, properties.getPropertyValue("DefaultContext"));
connected = true;
logger.info(String.format("connected: '%s'", unoUrl));
OfficeConnectionEvent connectionEvent = new OfficeConnectionEvent(this);
for (OfficeConnectionEventListener listener : connectionEventListeners) {
listener.connected(connectionEvent);
}
} catch (NoConnectException connectException) {
throw new ConnectException(String.format("connection failed: '%s'; %s", unoUrl, connectException.getMessage()));
} catch (Exception exception) {
throw new OfficeException("connection failed: "+ unoUrl, exception);
}
}
public boolean isConnected() {
return connected;
}
public synchronized void disconnect() {
logger.fine(String.format("disconnecting: '%s'", unoUrl));
bridgeComponent.dispose();
}
public Object getService(String serviceName) {
try {
return serviceManager.createInstanceWithContext(serviceName, componentContext);
} catch (Exception exception) {
throw new OfficeException(String.format("failed to obtain service '%s'", serviceName), exception);
}
}
}

View File

@ -1,25 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.util.EventObject;
class OfficeConnectionEvent extends EventObject {
private static final long serialVersionUID = 2060652797570876077L;
public OfficeConnectionEvent(OfficeConnection source) {
super(source);
}
}

View File

@ -1,23 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.util.EventListener;
interface OfficeConnectionEventListener extends EventListener {
void connected(OfficeConnectionEvent event);
void disconnected(OfficeConnectionEvent event);
}

View File

@ -1,15 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
public enum OfficeConnectionProtocol { PIPE, SOCKET }

View File

@ -1,19 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
public interface OfficeContext {
Object getService(String serviceName);
}

View File

@ -1,26 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
public class OfficeException extends RuntimeException {
private static final long serialVersionUID = 1L;
public OfficeException(String message) {
super(message);
}
public OfficeException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,30 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
/**
* An OfficeManager knows how to execute {@link OfficeTask}s.
* <p>
* An OfficeManager implementation will typically manage one or more
* {@link OfficeConnection}s.
*/
public interface OfficeManager {
void execute(OfficeTask task) throws OfficeException;
void start() throws OfficeException;
void stop() throws OfficeException;
boolean isRunning();
}

View File

@ -1,209 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import static org.artofsolving.jodconverter.process.ProcessManager.PID_NOT_FOUND;
import static org.artofsolving.jodconverter.process.ProcessManager.PID_UNKNOWN;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.artofsolving.jodconverter.process.ProcessManager;
import org.artofsolving.jodconverter.process.ProcessQuery;
import org.artofsolving.jodconverter.util.PlatformUtils;
class OfficeProcess {
private final File officeHome;
private final UnoUrl unoUrl;
private final String[] runAsArgs;
private final File templateProfileDir;
private final File instanceProfileDir;
private final ProcessManager processManager;
private Process process;
private long pid = PID_UNKNOWN;
private final Logger logger = Logger.getLogger(getClass().getName());
public OfficeProcess(File officeHome, UnoUrl unoUrl, String[] runAsArgs, File templateProfileDir, File workDir, ProcessManager processManager) {
this.officeHome = officeHome;
this.unoUrl = unoUrl;
this.runAsArgs = runAsArgs;
this.templateProfileDir = templateProfileDir;
this.instanceProfileDir = getInstanceProfileDir(workDir, unoUrl);
this.processManager = processManager;
}
public void start() throws IOException {
start(false);
}
public void start(boolean restart) throws IOException {
ProcessQuery processQuery = new ProcessQuery("soffice.bin", unoUrl.getAcceptString());
long existingPid = processManager.findPid(processQuery);
if (!(existingPid == PID_NOT_FOUND || existingPid == PID_UNKNOWN)) {
throw new IllegalStateException(String.format("a process with acceptString '%s' is already running; pid %d",
unoUrl.getAcceptString(), existingPid));
}
if (!restart) {
prepareInstanceProfileDir();
}
List<String> command = new ArrayList<String>();
File executable = OfficeUtils.getOfficeExecutable(officeHome);
if (runAsArgs != null) {
command.addAll(Arrays.asList(runAsArgs));
}
command.add(executable.getAbsolutePath());
command.add("-accept=" + unoUrl.getAcceptString() + ";urp;");
command.add("-env:UserInstallation=" + OfficeUtils.toUrl(instanceProfileDir));
command.add("-headless");
command.add("-nocrashreport");
command.add("-nodefault");
command.add("-nofirststartwizard");
command.add("-nolockcheck");
command.add("-nologo");
command.add("-norestore");
ProcessBuilder processBuilder = new ProcessBuilder(command);
if (PlatformUtils.isWindows()) {
addBasisAndUrePaths(processBuilder);
}
logger.info(String.format("starting process with acceptString '%s' and profileDir '%s'", unoUrl, instanceProfileDir));
process = processBuilder.start();
pid = processManager.findPid(processQuery);
if (pid == PID_NOT_FOUND) {
throw new IllegalStateException(String.format("process with acceptString '%s' started but its pid could not be found",
unoUrl.getAcceptString()));
}
logger.info("started process" + (pid != PID_UNKNOWN ? "; pid = " + pid : ""));
}
private File getInstanceProfileDir(File workDir, UnoUrl unoUrl) {
String dirName = ".jodconverter_" + unoUrl.getAcceptString().replace(',', '_').replace('=', '-');
return new File(workDir, dirName);
}
private void prepareInstanceProfileDir() throws OfficeException {
if (instanceProfileDir.exists()) {
logger.warning(String.format("profile dir '%s' already exists; deleting", instanceProfileDir));
deleteProfileDir();
}
if (templateProfileDir != null) {
try {
FileUtils.copyDirectory(templateProfileDir, instanceProfileDir);
} catch (IOException ioException) {
throw new OfficeException("failed to create profileDir", ioException);
}
}
}
public void deleteProfileDir() {
if (instanceProfileDir != null) {
try {
FileUtils.deleteDirectory(instanceProfileDir);
} catch (IOException ioException) {
File oldProfileDir = new File(instanceProfileDir.getParentFile(), instanceProfileDir.getName() + ".old." + System.currentTimeMillis());
if (instanceProfileDir.renameTo(oldProfileDir)) {
logger.warning("could not delete profileDir: " + ioException.getMessage() + "; renamed it to " + oldProfileDir);
} else {
logger.severe("could not delete profileDir: " + ioException.getMessage());
}
}
}
}
private void addBasisAndUrePaths(ProcessBuilder processBuilder) throws IOException {
// see http://wiki.services.openoffice.org/wiki/ODF_Toolkit/Efforts/Three-Layer_OOo
File basisLink = new File(officeHome, "basis-link");
if (!basisLink.isFile()) {
logger.fine("no %OFFICE_HOME%/basis-link found; assuming it's OOo 2.x and we don't need to append URE and Basic paths");
return;
}
String basisLinkText = FileUtils.readFileToString(basisLink).trim();
File basisHome = new File(officeHome, basisLinkText);
File basisProgram = new File(basisHome, "program");
File ureLink = new File(basisHome, "ure-link");
String ureLinkText = FileUtils.readFileToString(ureLink).trim();
File ureHome = new File(basisHome, ureLinkText);
File ureBin = new File(ureHome, "bin");
Map<String,String> environment = processBuilder.environment();
// Windows environment variables are case insensitive but Java maps are not :-/
// so let's make sure we modify the existing key
String pathKey = "PATH";
for (String key : environment.keySet()) {
if ("PATH".equalsIgnoreCase(key)) {
pathKey = key;
}
}
String path = environment.get(pathKey) + ";" + ureBin.getAbsolutePath() + ";" + basisProgram.getAbsolutePath();
logger.fine(String.format("setting %s to \"%s\"", pathKey, path));
environment.put(pathKey, path);
}
public boolean isRunning() {
if (process == null) {
return false;
}
return getExitCode() == null;
}
private class ExitCodeRetryable extends Retryable {
private int exitCode;
protected void attempt() throws TemporaryException, Exception {
try {
exitCode = process.exitValue();
} catch (IllegalThreadStateException illegalThreadStateException) {
throw new TemporaryException(illegalThreadStateException);
}
}
public int getExitCode() {
return exitCode;
}
}
public Integer getExitCode() {
try {
return process.exitValue();
} catch (IllegalThreadStateException exception) {
return null;
}
}
public int getExitCode(long retryInterval, long retryTimeout) throws RetryTimeoutException {
try {
ExitCodeRetryable retryable = new ExitCodeRetryable();
retryable.execute(retryInterval, retryTimeout);
return retryable.getExitCode();
} catch (RetryTimeoutException retryTimeoutException) {
throw retryTimeoutException;
} catch (Exception exception) {
throw new OfficeException("could not get process exit code", exception);
}
}
public int forciblyTerminate(long retryInterval, long retryTimeout) throws IOException, RetryTimeoutException {
logger.info(String.format("trying to forcibly terminate process: '" + unoUrl + "'" + (pid != PID_UNKNOWN ? " (pid " + pid + ")" : "")));
processManager.kill(process, pid);
return getExitCode(retryInterval, retryTimeout);
}
}

View File

@ -1,19 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
public interface OfficeTask {
void execute(OfficeContext context) throws OfficeException;
}

View File

@ -1,161 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.artofsolving.jodconverter.util.ConfigUtils;
import org.artofsolving.jodconverter.util.PlatformUtils;
import com.sun.star.beans.PropertyValue;
import com.sun.star.uno.UnoRuntime;
public class OfficeUtils {
public static final String SERVICE_DESKTOP = "com.sun.star.frame.Desktop";
public static final String OFFICE_HOME_KEY = "office.home";
public static final String DEFAULT_OFFICE_HOME_VALUE = "default";
private OfficeUtils() {
throw new AssertionError("utility class must not be instantiated");
}
public static <T> T cast(Class<T> type, Object object) {
return (T) UnoRuntime.queryInterface(type, object);
}
public static PropertyValue property(String name, Object value) {
PropertyValue propertyValue = new PropertyValue();
propertyValue.Name = name;
propertyValue.Value = value;
return propertyValue;
}
@SuppressWarnings("unchecked")
public static PropertyValue[] toUnoProperties(Map<String,?> properties) {
PropertyValue[] propertyValues = new PropertyValue[properties.size()];
int i = 0;
for (Map.Entry<String,?> entry : properties.entrySet()) {
Object value = entry.getValue();
if (value instanceof Map) {
Map<String,Object> subProperties = (Map<String,Object>) value;
value = toUnoProperties(subProperties);
}
propertyValues[i++] = property(entry.getKey(), value);
}
return propertyValues;
}
public static String toUrl(File file) {
String path = file.toURI().getRawPath();
String url = path.startsWith("//") ? "file:" + path : "file://" + path;
return url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
}
public static File getDefaultOfficeHome() {
Properties properties = new Properties();
String customizedConfigPath = ConfigUtils.getCustomizedConfigPath();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(customizedConfigPath));
properties.load(bufferedReader);
restorePropertiesFromEnvFormat(properties);
} catch (Exception e) {}
String officeHome = properties.getProperty(OFFICE_HOME_KEY);
if (officeHome != null && !DEFAULT_OFFICE_HOME_VALUE.equals(officeHome)) {
return new File(officeHome);
}
if (PlatformUtils.isWindows()) {
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
String officePluginPath = ConfigUtils.getOfficePluginPath();
String programFiles = System.getenv("ProgramFiles(x86)");
if (programFiles == null) {
programFiles = System.getenv("ProgramFiles");
}
return findOfficeHome(
programFiles + File.separator + "OpenOffice 4",
programFiles + File.separator + "LibreOffice 4",
officePluginPath + File.separator + "windows-office"
);
} else if (PlatformUtils.isMac()) {
return findOfficeHome(
"/Applications/OpenOffice.org.app/Contents",
"/Applications/OpenOffice.app/Contents",
"/Applications/LibreOffice.app/Contents"
);
} else {
// Linux or other *nix variants
return findOfficeHome(
"/opt/openoffice.org3",
"/opt/openoffice",
"/opt/libreoffice",
"/opt/openoffice4",
"/usr/lib/openoffice",
"/usr/lib/libreoffice"
);
}
}
private static File findOfficeHome(String... knownPaths) {
for (String path : knownPaths) {
File home = new File(path);
if (getOfficeExecutable(home).isFile()) {
return home;
}
}
return null;
}
public static File getOfficeExecutable(File officeHome) {
if (PlatformUtils.isMac()) {
return new File(officeHome, "MacOS/soffice");
} else {
return new File(officeHome, "program/soffice.bin");
}
}
/**
* SpringBoot application.properties 支持从环境变量获取值
* @param properties
*/
public synchronized static void restorePropertiesFromEnvFormat(Properties properties) {
Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Object, Object> entry = iterator.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if (value.trim().startsWith("${") && value.trim().endsWith("}")) {
int beginIndex = value.indexOf(":");
if (beginIndex < 0) {
beginIndex = value.length() - 1;
}
int endIndex = value.length() - 1;
String envKey = value.substring(2, beginIndex);
String envValue = System.getenv(envKey);
if (envValue == null || "".equals(envValue.trim())) {
value = value.substring(beginIndex + 1, endIndex);
} else {
value = envValue;
}
properties.setProperty(key, value);
}
}
}
}

View File

@ -1,110 +0,0 @@
//
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
class PooledOfficeManager implements OfficeManager {
private final PooledOfficeManagerSettings settings;
private final ManagedOfficeProcess managedOfficeProcess;
private final SuspendableThreadPoolExecutor taskExecutor;
private volatile boolean stopping = false;
private int taskCount;
private Future<?> currentTask;
private final Logger logger = Logger.getLogger(getClass().getName());
private OfficeConnectionEventListener connectionEventListener = new OfficeConnectionEventListener() {
public void connected(OfficeConnectionEvent event) {
taskCount = 0;
taskExecutor.setAvailable(true);
}
public void disconnected(OfficeConnectionEvent event) {
taskExecutor.setAvailable(false);
if (stopping) {
// expected
stopping = false;
} else {
logger.warning("connection lost unexpectedly; attempting restart");
if (currentTask != null) {
currentTask.cancel(true);
}
managedOfficeProcess.restartDueToLostConnection();
}
}
};
public PooledOfficeManager(UnoUrl unoUrl) {
this(new PooledOfficeManagerSettings(unoUrl));
}
public PooledOfficeManager(PooledOfficeManagerSettings settings) {
this.settings = settings;
managedOfficeProcess = new ManagedOfficeProcess(settings);
managedOfficeProcess.getConnection().addConnectionEventListener(connectionEventListener);
taskExecutor = new SuspendableThreadPoolExecutor(new NamedThreadFactory("OfficeTaskThread"));
}
public void execute(final OfficeTask task) throws OfficeException {
Future<?> futureTask = taskExecutor.submit(new Runnable() {
public void run() {
if (settings.getMaxTasksPerProcess() > 0 && ++taskCount == settings.getMaxTasksPerProcess() + 1) {
logger.info(String.format("reached limit of %d maxTasksPerProcess: restarting", settings.getMaxTasksPerProcess()));
taskExecutor.setAvailable(false);
stopping = true;
managedOfficeProcess.restartAndWait();
//FIXME taskCount will be 0 rather than 1 at this point
}
task.execute(managedOfficeProcess.getConnection());
}
});
currentTask = futureTask;
try {
futureTask.get(settings.getTaskExecutionTimeout(), TimeUnit.MILLISECONDS);
} catch (TimeoutException timeoutException) {
managedOfficeProcess.restartDueToTaskTimeout();
throw new OfficeException("task did not complete within timeout", timeoutException);
} catch (ExecutionException executionException) {
if (executionException.getCause() instanceof OfficeException) {
throw (OfficeException) executionException.getCause();
} else {
throw new OfficeException("task failed", executionException.getCause());
}
} catch (Exception exception) {
throw new OfficeException("task failed", exception);
}
}
public void start() throws OfficeException {
managedOfficeProcess.startAndWait();
}
public void stop() throws OfficeException {
taskExecutor.setAvailable(false);
stopping = true;
taskExecutor.shutdownNow();
managedOfficeProcess.stopAndWait();
}
public boolean isRunning() {
return managedOfficeProcess.isConnected();
}
}

View File

@ -1,43 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
class PooledOfficeManagerSettings extends ManagedOfficeProcessSettings {
public static final long DEFAULT_TASK_EXECUTION_TIMEOUT = 120000L;
public static final int DEFAULT_MAX_TASKS_PER_PROCESS = 200;
private long taskExecutionTimeout = DEFAULT_TASK_EXECUTION_TIMEOUT;
private int maxTasksPerProcess = DEFAULT_MAX_TASKS_PER_PROCESS;
public PooledOfficeManagerSettings(UnoUrl unoUrl) {
super(unoUrl);
}
public long getTaskExecutionTimeout() {
return taskExecutionTimeout;
}
public void setTaskExecutionTimeout(long taskExecutionTimeout) {
this.taskExecutionTimeout = taskExecutionTimeout;
}
public int getMaxTasksPerProcess() {
return maxTasksPerProcess;
}
public void setMaxTasksPerProcess(int maxTasksPerProcess) {
this.maxTasksPerProcess = maxTasksPerProcess;
}
}

View File

@ -1,110 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.io.File;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.artofsolving.jodconverter.process.ProcessManager;
class ProcessPoolOfficeManager implements OfficeManager {
private final BlockingQueue<PooledOfficeManager> pool;
private final PooledOfficeManager[] pooledManagers;
private final long taskQueueTimeout;
private volatile boolean running = false;
private final Logger logger = Logger.getLogger(ProcessPoolOfficeManager.class.getName());
public ProcessPoolOfficeManager(File officeHome, UnoUrl[] unoUrls, String[] runAsArgs, File templateProfileDir, File workDir,
long retryTimeout, long taskQueueTimeout, long taskExecutionTimeout, int maxTasksPerProcess,
ProcessManager processManager) {
this.taskQueueTimeout = taskQueueTimeout;
pool = new ArrayBlockingQueue<PooledOfficeManager>(unoUrls.length);
pooledManagers = new PooledOfficeManager[unoUrls.length];
for (int i = 0; i < unoUrls.length; i++) {
PooledOfficeManagerSettings settings = new PooledOfficeManagerSettings(unoUrls[i]);
settings.setRunAsArgs(runAsArgs);
settings.setTemplateProfileDir(templateProfileDir);
settings.setWorkDir(workDir);
settings.setOfficeHome(officeHome);
settings.setRetryTimeout(retryTimeout);
settings.setTaskExecutionTimeout(taskExecutionTimeout);
settings.setMaxTasksPerProcess(maxTasksPerProcess);
settings.setProcessManager(processManager);
pooledManagers[i] = new PooledOfficeManager(settings);
}
logger.info("ProcessManager implementation is " + processManager.getClass().getSimpleName());
}
public synchronized void start() throws OfficeException {
for (int i = 0; i < pooledManagers.length; i++) {
pooledManagers[i].start();
releaseManager(pooledManagers[i]);
}
running = true;
}
public void execute(OfficeTask task) throws IllegalStateException, OfficeException {
if (!running) {
throw new IllegalStateException("this OfficeManager is currently stopped");
}
PooledOfficeManager manager = null;
try {
manager = acquireManager();
if (manager == null) {
throw new OfficeException("no office manager available");
}
manager.execute(task);
} finally {
if (manager != null) {
releaseManager(manager);
}
}
}
public synchronized void stop() throws OfficeException {
running = false;
logger.info("stopping");
pool.clear();
for (int i = 0; i < pooledManagers.length; i++) {
pooledManagers[i].stop();
}
logger.info("stopped");
}
private PooledOfficeManager acquireManager() {
try {
return pool.poll(taskQueueTimeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException interruptedException) {
throw new OfficeException("interrupted", interruptedException);
}
}
private void releaseManager(PooledOfficeManager manager) {
try {
pool.put(manager);
} catch (InterruptedException interruptedException) {
throw new OfficeException("interrupted", interruptedException);
}
}
public boolean isRunning() {
return running;
}
}

View File

@ -1,23 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
class RetryTimeoutException extends Exception {
private static final long serialVersionUID = -3704437769955257514L;
public RetryTimeoutException(Throwable cause) {
super(cause);
}
}

View File

@ -1,55 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
abstract class Retryable {
/**
* @throws TemporaryException for an error condition that can be temporary - i.e. retrying later could be successful
* @throws Exception for all other error conditions
*/
protected abstract void attempt() throws TemporaryException, Exception;
public void execute(long interval, long timeout) throws RetryTimeoutException, Exception {
execute(0L, interval, timeout);
}
public void execute(long delay, long interval, long timeout) throws RetryTimeoutException, Exception {
long start = System.currentTimeMillis();
if (delay > 0L) {
sleep(delay);
}
while (true) {
try {
attempt();
return;
} catch (TemporaryException temporaryException) {
if (System.currentTimeMillis() - start < timeout) {
sleep(interval);
// continue
} else {
throw new RetryTimeoutException(temporaryException.getCause());
}
}
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException interruptedException) {
// continue
}
}
}

View File

@ -1,59 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class SuspendableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean available = false;
private ReentrantLock suspendLock = new ReentrantLock();
private Condition availableCondition = suspendLock.newCondition();
public SuspendableThreadPoolExecutor(ThreadFactory threadFactory) {
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
}
@Override
protected void beforeExecute(Thread thread, Runnable task) {
super.beforeExecute(thread, task);
suspendLock.lock();
try {
while (!available) {
availableCondition.await();
}
} catch (InterruptedException interruptedException) {
thread.interrupt();
} finally {
suspendLock.unlock();
}
}
public void setAvailable(boolean available) {
suspendLock.lock();
try {
this.available = available;
if (available) {
availableCondition.signalAll();
}
} finally {
suspendLock.unlock();
}
}
}

View File

@ -1,32 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
import java.math.BigDecimal;
/**
* Represents an error condition that can be temporary, i.e. that could go
* away by simply retrying the same operation after an interval.
*/
class TemporaryException extends Exception {
private static final long serialVersionUID = 7237380113208327295L;
public TemporaryException(Throwable cause) {
super(cause);
}
public static void main(String[] args) {
System.out.println(new BigDecimal("7412611111110.99"));
}
}

View File

@ -1,62 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.office;
/**
* Encapsulates the UNO Interprocess Connection type and parameters.
* <p>
* OpenOffice.org supports two connection types: TCP sockets and named pipes.
* Named pipes are marginally faster and do not take up a TCP port, but they
* require native libraries, which means setting <em>java.library.path</em>
* when starting Java. E.g. on Linux
* <pre>
* java -Djava.library.path=/opt/openoffice.org/ure/lib ...
* </pre>
* <p>
* See <a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Opening_a_Connection">Opening a Connection</a>
* in the OpenOffice.org Developer's Guide for more details.
*/
class UnoUrl {
private final String acceptString;
private final String connectString;
private UnoUrl(String acceptString, String connectString) {
this.acceptString = acceptString;
this.connectString = connectString;
}
public static UnoUrl socket(int port) {
String socketString = "socket,host=127.0.0.1,port=" + port;
return new UnoUrl(socketString, socketString + ",tcpNoDelay=1");
}
public static UnoUrl pipe(String pipeName) {
String pipeString = "pipe,name=" + pipeName;
return new UnoUrl(pipeString, pipeString);
}
public String getAcceptString() {
return acceptString;
}
public String getConnectString() {
return connectString;
}
@Override
public String toString() {
return connectString;
}
}

View File

@ -1,82 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.process;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
/**
* {@link ProcessManager} implementation for Linux. Uses the <tt>ps</tt>
* and <tt>kill</tt> commands.
* <p>
* Should Work on Solaris too, except that the command line string
* returned by <tt>ps</tt> there is limited to 80 characters and this affects
* {@link #findPid(String)}.
*/
public class LinuxProcessManager implements ProcessManager {
private static final Pattern PS_OUTPUT_LINE = Pattern.compile("^\\s*(\\d+)\\s+(.*)$");
private String[] runAsArgs;
public void setRunAsArgs(String... runAsArgs) {
this.runAsArgs = runAsArgs;
}
protected String[] psCommand() {
return new String[] { "/bin/ps", "-e", "-o", "pid,args" };
}
public long findPid(ProcessQuery query) throws IOException {
String regex = Pattern.quote(query.getCommand()) + ".*" + Pattern.quote(query.getArgument());
Pattern commandPattern = Pattern.compile(regex);
for (String line : execute(psCommand())) {
Matcher lineMatcher = PS_OUTPUT_LINE.matcher(line);
if (lineMatcher.matches()) {
String command = lineMatcher.group(2);
Matcher commandMatcher = commandPattern.matcher(command);
if (commandMatcher.find()) {
return Long.parseLong(lineMatcher.group(1));
}
}
}
return PID_NOT_FOUND;
}
public void kill(Process process, long pid) throws IOException {
if (pid <= 0) {
throw new IllegalArgumentException("invalid pid: " + pid);
}
execute("/bin/kill", "-KILL", Long.toString(pid));
}
private List<String> execute(String... args) throws IOException {
String[] command;
if (runAsArgs != null) {
command = new String[runAsArgs.length + args.length];
System.arraycopy(runAsArgs, 0, command, 0, runAsArgs.length);
System.arraycopy(args, 0, command, runAsArgs.length, args.length);
} else {
command = args;
}
Process process = new ProcessBuilder(command).start();
@SuppressWarnings("unchecked")
List<String> lines = IOUtils.readLines(process.getInputStream());
return lines;
}
}

View File

@ -1,32 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.process;
import java.io.IOException;
public interface ProcessManager {
public static final long PID_NOT_FOUND = -2;
public static final long PID_UNKNOWN = -1;
void kill(Process process, long pid) throws IOException;
/**
* @param query
* @return the pid if found, {@link #PID_NOT_FOUND} if not,
* or {@link #PID_UNKNOWN} if this implementation is unable to find out
* @throws IOException
*/
long findPid(ProcessQuery query) throws IOException;
}

View File

@ -1,33 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.process;
public class ProcessQuery {
private final String command;
private final String argument;
public ProcessQuery(String command, String argument) {
this.command = command;
this.argument = argument;
}
public String getCommand() {
return command;
}
public String getArgument() {
return argument;
}
}

View File

@ -1,25 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.process;
public class PureJavaProcessManager implements ProcessManager {
public long findPid(ProcessQuery query) {
return PID_UNKNOWN;
}
public void kill(Process process, long pid) {
process.destroy();
}
}

View File

@ -1,71 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.process;
import java.io.IOException;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.ptql.ProcessFinder;
/**
* {@link ProcessManager} implementation that uses the SIGAR library.
* <p>
* Requires the sigar.jar in the classpath and the appropriate system-specific
* native library (e.g. <tt>libsigar-x86-linux.so</tt> on Linux x86) available
* in the <em>java.library.path</em>.
* <p>
* See the <a href="http://support.hyperic.com/display/SIGAR">SIGAR site</a>
* for documentation and downloads.
*/
public class SigarProcessManager implements ProcessManager {
public long findPid(ProcessQuery query) throws IOException {
Sigar sigar = new Sigar();
try {
long[] pids = ProcessFinder.find(sigar, "State.Name.eq=" + query.getCommand());
for (int i = 0; i < pids.length; i++) {
String[] arguments = sigar.getProcArgs(pids[i]);
if (arguments != null && argumentMatches(arguments, query.getArgument())) {
return pids[i];
}
}
return PID_NOT_FOUND;
} catch (SigarException sigarException) {
throw new IOException("findPid failed", sigarException);
} finally {
sigar.close();
}
}
public void kill(Process process, long pid) throws IOException {
Sigar sigar = new Sigar();
try {
sigar.kill(pid, Sigar.getSigNum("KILL"));
} catch (SigarException sigarException) {
throw new IOException("kill failed", sigarException);
} finally {
sigar.close();
}
}
private boolean argumentMatches(String[] arguments, String expected) {
for (String argument : arguments) {
if (argument.contains(expected)) {
return true;
}
}
return false;
}
}

View File

@ -1,54 +0,0 @@
package org.artofsolving.jodconverter.util;
import java.io.File;
/**
* @author : kl
**/
public class ConfigUtils {
private static final String MAIN_DIRECTORY_NAME = "server";
private static final String OFFICE_PLUGIN_NAME = "office-plugin";
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(MAIN_DIRECTORY_NAME)) {
userDir = userDir + separator + "src" + separator + "main";
} else {
userDir = userDir + separator + MAIN_DIRECTORY_NAME + separator + "src" + separator + "main";
}
}
return userDir;
}
public static String getOfficePluginPath() {
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(OFFICE_PLUGIN_NAME)) {
userDir = userDir + separator + OFFICE_PLUGIN_NAME;
}
}
return userDir;
}
public static String getCustomizedConfigPath() {
String homePath = getHomePath();
String separator = java.io.File.separator;
return homePath + separator + "config" + separator + "application.properties";
}
}

View File

@ -1,35 +0,0 @@
//
// JODConverter - Java OpenDocument Converter
// Copyright 2004-2012 Mirko Nasato and contributors
//
// JODConverter is Open Source software, you can redistribute it and/or
// modify it under either (at your option) of the following licenses
//
// 1. The GNU Lesser General Public License v3 (or later)
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
// 2. The Apache License, Version 2.0
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
//
package org.artofsolving.jodconverter.util;
public class PlatformUtils {
private static final String OS_NAME = System.getProperty("os.name").toLowerCase();
private PlatformUtils() {
throw new AssertionError("utility class must not be instantiated");
}
public static boolean isLinux() {
return OS_NAME.startsWith("linux");
}
public static boolean isMac() {
return OS_NAME.startsWith("mac");
}
public static boolean isWindows() {
return OS_NAME.startsWith("windows");
}
}

View File

@ -1,188 +0,0 @@
[
{
"name": "Portable Document Format",
"extension": "pdf",
"mediaType": "application/pdf",
"storePropertiesByFamily": {
"DRAWING": {"FilterName": "draw_pdf_Export"},
"SPREADSHEET": {"FilterName": "calc_pdf_Export"},
"PRESENTATION": {"FilterName": "impress_pdf_Export"},
"TEXT": {"FilterName": "writer_pdf_Export"}
}
},
{
"name": "Macromedia Flash",
"extension": "swf",
"mediaType": "application/x-shockwave-flash",
"storePropertiesByFamily": {
"DRAWING": {"FilterName": "draw_flash_Export"},
"PRESENTATION": {"FilterName": "impress_flash_Export"}
}
},
{
"name": "HTML",
"extension": "html",
"mediaType": "text/html",
"inputFamily": "TEXT",
"storePropertiesByFamily": {
"SPREADSHEET": {"FilterName": "HTML (StarCalc)"},
"PRESENTATION": {"FilterName": "impress_html_Export"},
"TEXT": {"FilterName": "HTML (StarWriter)"}
}
},
{
"name": "OpenDocument Text",
"extension": "odt",
"mediaType": "application/vnd.oasis.opendocument.text",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "writer8"}}
},
{
"name": "OpenOffice.org 1.0 Text Document",
"extension": "sxw",
"mediaType": "application/vnd.sun.xml.writer",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "StarOffice XML (Writer)"}}
},
{
"name": "Microsoft Word",
"extension": "doc",
"mediaType": "application/msword",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 97"}}
},
{
"name": "Microsoft Word 2007 XML",
"extension": "docx",
"mediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"inputFamily": "TEXT"
},
{
"name": "Rich Text Format",
"extension": "rtf",
"mediaType": "text/rtf",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "Rich Text Format"}}
},
{
"name": "WordPerfect",
"extension": "wpd",
"mediaType": "application/wordperfect",
"inputFamily": "TEXT"
},
{
"name": "Plain Text",
"extension": "txt",
"mediaType": "text/plain",
"inputFamily": "TEXT",
"loadProperties": {
"FilterName": "Text (encoded)",
"FilterOptions": "utf8"
},
"storePropertiesByFamily": {"TEXT": {
"FilterName": "Text (encoded)",
"FilterOptions": "utf8"
}}
},
{
"name": "MediaWiki wikitext",
"extension": "wiki",
"mediaType": "text/x-wiki",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MediaWiki"}}
},
{
"name": "OpenDocument Spreadsheet",
"extension": "ods",
"mediaType": "application/vnd.oasis.opendocument.spreadsheet",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "calc8"}}
},
{
"name": "OpenOffice.org 1.0 Spreadsheet",
"extension": "sxc",
"mediaType": "application/vnd.sun.xml.calc",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "StarOffice XML (Calc)"}}
},
{
"name": "Microsoft Excel",
"extension": "xls",
"mediaType": "application/vnd.ms-excel",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 97"}}
},
{
"name": "Microsoft Excel 2007 XML",
"extension": "xlsx",
"mediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"inputFamily": "SPREADSHEET"
},
{
"name": "Comma Separated Values",
"extension": "csv",
"mediaType": "text/csv",
"inputFamily": "SPREADSHEET",
"loadProperties": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "44,34,0"
},
"storePropertiesByFamily": {"SPREADSHEET": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "44,34,0"
}}
},
{
"name": "Tab Separated Values",
"extension": "tsv",
"mediaType": "text/tab-separated-values",
"inputFamily": "SPREADSHEET",
"loadProperties": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "9,34,0"
},
"storePropertiesByFamily": {"SPREADSHEET": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "9,34,0"
}}
},
{
"name": "OpenDocument Presentation",
"extension": "odp",
"mediaType": "application/vnd.oasis.opendocument.presentation",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "impress8"}}
},
{
"name": "OpenOffice.org 1.0 Presentation",
"extension": "sxi",
"mediaType": "application/vnd.sun.xml.impress",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "StarOffice XML (Impress)"}}
},
{
"name": "Microsoft PowerPoint",
"extension": "ppt",
"mediaType": "application/vnd.ms-powerpoint",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 97"}}
},
{
"name": "Microsoft PowerPoint 2007 XML",
"extension": "pptx",
"mediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"inputFamily": "PRESENTATION"
},
{
"name": "OpenDocument Drawing",
"extension": "odg",
"mediaType": "application/vnd.oasis.opendocument.graphics",
"inputFamily": "DRAWING",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw8"}}
},
{
"name": "Scalable Vector Graphics",
"extension": "svg",
"mediaType": "image/svg+xml",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw_svg_Export"}}
}
]

View File

@ -1,54 +0,0 @@
<!--***********************************************************
*
* 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

@ -1,124 +0,0 @@
<!--***********************************************************
*
* 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>

View File

@ -1,960 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************************
This is the main transformation style sheet for transforming.
Only use with OOo 2.0
Owner: fpe@openoffice.org
=========================================================================
Changes Log
May 24 2004 Created
Aug 24 2004 Fixed for help2 CWS
Aug 27 2004 Added css link, fixed missing embed-mode for variable
Removed width/height for images
Sep 03 2004 Modularized xsl, added some embedded modes
Oct 08 2004 Fixed bug wrong mode "embedded" for links
Added embedded modes for embed and embedvar (for cascaded embeds)
Added <p> tags around falsely embedded pars and vars
Dec 08 2004 #i38483#, fixed wrong handling of web links
#i37377#, fixed missing usage of Database parameter for switching
Jan 04 2005 #i38905#, fixed buggy branding replacement template
Mar 17 2005 #i43972#, added language info to image URL, evaluate Language parameter
evaluate new localize attribute in images
May 10 2005 #i48785#, fixed wrong setting of distrib variable
Aug 16 2005 workaround for #i53365#
Aug 19 2005 fixed missing list processing in embedded sections
Aug 19 2005 #i53535#, fixed wrong handling of Database parameter
Oct 17 2006 #i70462#, disabled sorting to avoid output of error messages to console
Jun 15 2009 #i101799#, fixed wrong handling of http URLs with anchors
***********************************************************************//-->
<!--***********************************************************
*
* 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" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="html"/>
<!--
############################
# Variables and Parameters #
############################
//-->
<!-- General Usage -->
<xsl:variable name="am" select="'&amp;'"/>
<xsl:variable name="sl" select="'/'"/>
<xsl:variable name="qt" select="'&quot;'"/>
<!-- generic Icon alt text -->
<xsl:variable name="alttext" select="'text/shared/00/icon_alt.xhp'"/>
<!-- For calculating pixel sizes -->
<xsl:variable name="dpi" select="'96'"/>
<xsl:variable name="dpcm" select="'38'"/>
<!-- Product brand variables used in the help files -->
<xsl:variable name="brand1" select="'$[officename]'"/>
<xsl:variable name="brand2" select="'$[officeversion]'"/>
<xsl:variable name="brand3" select="'%PRODUCTNAME'"/>
<xsl:variable name="brand4" select="'%PRODUCTVERSION'"/>
<!-- meta data variables from the help file -->
<xsl:variable name="filename" select="/helpdocument/meta/topic/filename"/>
<xsl:variable name="topic_id" select="/helpdocument/meta/topic/@id"/>
<xsl:variable name="topic_status" select="/helpdocument/meta/topic/@status"/>
<xsl:variable name="title" select="/helpdocument/meta/topic/title"/>
<xsl:variable name="doclang" select="/helpdocument/meta/topic/title/@xml-lang"/>
<!-- Module and the corresponding switching values-->
<xsl:param name="Database" select="'swriter'"/>
<xsl:variable name="module" select="$Database"/>
<xsl:variable name="appl">
<xsl:choose>
<xsl:when test="$module = 'swriter'"><xsl:value-of select="'WRITER'"/></xsl:when>
<xsl:when test="$module = 'scalc'"><xsl:value-of select="'CALC'"/></xsl:when>
<xsl:when test="$module = 'sdraw'"><xsl:value-of select="'DRAW'"/></xsl:when>
<xsl:when test="$module = 'simpress'"><xsl:value-of select="'IMPRESS'"/></xsl:when>
<xsl:when test="$module = 'schart'"><xsl:value-of select="'CHART'"/></xsl:when>
<xsl:when test="$module = 'sbasic'"><xsl:value-of select="'BASIC'"/></xsl:when>
<xsl:when test="$module = 'smath'"><xsl:value-of select="'MATH'"/></xsl:when>
</xsl:choose>
</xsl:variable>
<!-- the other parameters given by the help caller -->
<xsl:param name="System" select="'WIN'"/>
<xsl:param name="productname" select="'Office'"/>
<xsl:param name="productversion" select="''"/>
<xsl:variable name="pversion">
<xsl:value-of select="translate($productversion,' ','')"/>
</xsl:variable>
<!-- this is were the images are -->
<xsl:param name="imgrepos" select="''"/>
<xsl:param name="Id" />
<!-- (lame) distinction between OS and Commercial -->
<xsl:param name="distrib">
<xsl:choose>
<xsl:when test="starts-with($productname,'OpenOffice')">
<xsl:value-of select="'OpenSource'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'COMMERCIAL'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="Language" select="'en-US'"/>
<xsl:variable name="lang" select="$Language"/>
<xsl:param name="ExtensionId" select="''"/>
<xsl:param name="ExtensionPath" select="''"/>
<!-- parts of help and image urls -->
<xsl:variable name="help_url_prefix" select="'vnd.sun.star.help://'"/>
<xsl:variable name="img_url_prefix" select="concat('vnd.sun.star.zip://',$imgrepos,'/')"/>
<xsl:variable name="urlpost" select="concat('?Language=',$lang,$am,'System=',$System,$am,'UseDB=no')"/>
<xsl:variable name="urlpre" select="$help_url_prefix" />
<xsl:variable name="linkprefix" select="$urlpre"/>
<xsl:variable name="linkpostfix" select="$urlpost"/>
<xsl:variable name="css" select="'default.css'"/>
<!-- images for notes, tips and warnings -->
<xsl:variable name="note_img" select="concat($img_url_prefix,'res/helpimg/note.png')"/>
<xsl:variable name="tip_img" select="concat($img_url_prefix,'res/helpimg/tip.png')"/>
<xsl:variable name="warning_img" select="concat($img_url_prefix,'res/helpimg/warning.png')"/>
<!--
#############
# Templates #
#############
//-->
<!-- Create the document skeleton -->
<xsl:template match="/">
<xsl:variable name="csslink" select="concat($urlpre,'/',$urlpost)"/>
<html>
<head>
<title><xsl:value-of select="$title"/></title>
<link href="{$csslink}" rel="Stylesheet" type="text/css" /> <!-- stylesheet link -->
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
</head>
<body lang="{$lang}">
<xsl:apply-templates select="/helpdocument/body"/>
</body>
</html>
</xsl:template>
<!-- AHELP -->
<xsl:template match="ahelp">
<xsl:if test="not(@visibility='hidden')"><span class="avis"><xsl:apply-templates /></span></xsl:if>
</xsl:template>
<!-- ALT -->
<xsl:template match="alt"/>
<!-- BOOKMARK -->
<xsl:template match="bookmark">
<a name="{@id}"></a>
<xsl:choose>
<xsl:when test="starts-with(@branch,'hid')" />
<xsl:otherwise><xsl:apply-templates /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="bookmark" mode="embedded" />
<!-- BOOKMARK_VALUE -->
<xsl:template match="bookmark_value" />
<!-- BR -->
<xsl:template match="br"><br /></xsl:template>
<!-- CAPTION -->
<xsl:template match="caption" />
<!-- CASE -->
<xsl:template match="case"><xsl:call-template name="insertcase" /></xsl:template>
<xsl:template match="case" mode="embedded">
<xsl:call-template name="insertcase">
<xsl:with-param name="embedded" select="'yes'"/>
</xsl:call-template>
</xsl:template>
<!-- CASEINLINE -->
<xsl:template match="caseinline"><xsl:call-template name="insertcase" /></xsl:template>
<xsl:template match="caseinline" mode="embedded">
<xsl:call-template name="insertcase">
<xsl:with-param name="embedded" select="'yes'"/>
</xsl:call-template>
</xsl:template>
<!-- COMMENT -->
<xsl:template match="comment" />
<xsl:template match="comment" mode="embedded"/>
<!-- CREATED -->
<xsl:template match="created" />
<!-- DEFAULT -->
<xsl:template match="default"><xsl:call-template name="insertdefault" /></xsl:template>
<xsl:template match="default" mode="embedded">
<xsl:call-template name="insertdefault">
<xsl:with-param name="embedded" select="'yes'"/>
</xsl:call-template>
</xsl:template>
<!-- DEFAULTINLINE -->
<xsl:template match="defaultinline"><xsl:call-template name="insertdefault" /></xsl:template>
<xsl:template match="defaultinline" mode="embedded">
<xsl:call-template name="insertdefault">
<xsl:with-param name="embedded" select="'yes'"/>
</xsl:call-template>
</xsl:template>
<!-- EMBED -->
<xsl:template match="embed"><xsl:call-template name="resolveembed"/></xsl:template>
<xsl:template match="embed" mode="embedded"><xsl:call-template name="resolveembed"/></xsl:template>
<!-- EMBEDVAR -->
<xsl:template match="embedvar"><xsl:call-template name="resolveembedvar"/></xsl:template>
<xsl:template match="embedvar" mode="embedded"><xsl:call-template name="resolveembedvar"/></xsl:template>
<!-- EMPH -->
<xsl:template match="emph">
<span class="emph"><xsl:apply-templates /></span>
</xsl:template>
<xsl:template match="emph" mode="embedded">
<span class="emph"><xsl:apply-templates /></span>
</xsl:template>
<!-- FILENAME -->
<xsl:template match="filename" />
<!-- HISTORY -->
<xsl:template match="history" />
<!-- IMAGE -->
<xsl:template match="image"><xsl:call-template name="insertimage"/></xsl:template>
<xsl:template match="image" mode="embedded"><xsl:call-template name="insertimage"/></xsl:template>
<!-- ITEM -->
<xsl:template match="item"><span class="{@type}"><xsl:apply-templates /></span></xsl:template>
<xsl:template match="item" mode="embedded"><span class="{@type}"><xsl:apply-templates /></span></xsl:template>
<!-- LASTEDITED -->
<xsl:template match="lastedited" />
<!-- LINK -->
<xsl:template match="link">
<xsl:choose> <!-- don't insert the heading link to itself -->
<xsl:when test="(concat('/',@href) = /helpdocument/meta/topic/filename) or (@href = /helpdocument/meta/topic/filename)">
<xsl:apply-templates />
</xsl:when>
<xsl:when test="contains(child::embedvar/@href,'/00/00000004.xhp#wie')"> <!-- special treatment of howtoget links -->
<xsl:call-template name="insert_howtoget">
<xsl:with-param name="linkhref" select="@href"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="createlink" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="link" mode="embedded">
<xsl:call-template name="createlink"/>
</xsl:template>
<!-- LIST -->
<xsl:template match="list">
<xsl:choose>
<xsl:when test="@type='ordered'">
<ol>
<xsl:if test="@startwith">
<xsl:attribute name="start"><xsl:value-of select="@startwith"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates />
</ol>
</xsl:when>
<xsl:otherwise>
<ul><xsl:apply-templates /></ul>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="list" mode="embedded">
<xsl:choose>
<xsl:when test="@type='ordered'">
<ol>
<xsl:if test="@startwith">
<xsl:attribute name="start"><xsl:value-of select="@startwith"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates mode="embedded"/>
</ol>
</xsl:when>
<xsl:otherwise>
<ul><xsl:apply-templates mode="embedded"/></ul>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- LISTITEM -->
<xsl:template match="listitem">
<li><xsl:apply-templates /></li>
</xsl:template>
<xsl:template match="listitem" mode="embedded">
<li><xsl:apply-templates mode="embedded"/></li>
</xsl:template>
<!-- META, SEE HEADER -->
<xsl:template match="meta" />
<!-- OBJECT (UNUSED) -->
<xsl:template match="object" />
<!-- PARAGRAPH -->
<xsl:template match="paragraph">
<xsl:choose>
<xsl:when test="@role='heading'">
<xsl:call-template name="insertheading">
<xsl:with-param name="level" select="@level"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains(' note warning tip ',@role)">
<xsl:call-template name="insertnote">
<xsl:with-param name="type" select="@role" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains(descendant::embedvar/@href,'/00/00000004.xhp#wie')"> <!-- special treatment of howtoget links -->
<xsl:apply-templates />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="insertpara" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="paragraph" mode="embedded">
<xsl:choose>
<xsl:when test="@role='heading'"> <!-- increase the level of headings that are embedded -->
<!--
The internal sablotron processor does not seem to support the number function.
Therefore, we need a workaround for
<xsl:variable name="level"><xsl:value-of select="number(@level)+1"/></xsl:variable>
-->
<xsl:variable name="newlevel">
<xsl:choose>
<xsl:when test="@level='1'"><xsl:value-of select="'2'"/></xsl:when>
<xsl:when test="@level='2'"><xsl:value-of select="'2'"/></xsl:when>
<xsl:when test="@level='3'"><xsl:value-of select="'3'"/></xsl:when>
<xsl:when test="@level='4'"><xsl:value-of select="'4'"/></xsl:when>
<xsl:when test="@level='5'"><xsl:value-of select="'5'"/></xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="insertheading">
<xsl:with-param name="level" select="$newlevel"/>
<xsl:with-param name="embedded" select="'yes'"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains(' note warning tip ',@role)">
<xsl:call-template name="insertnote">
<xsl:with-param name="type" select="@role" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains(descendant::embedvar/@href,'/00/00000004.xhp#wie')"> <!-- special treatment of howtoget links -->
<xsl:apply-templates />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="insertpara" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- SECTION -->
<xsl:template match="section">
<a name="{@id}"></a>
<xsl:choose>
<xsl:when test="@id='relatedtopics'">
<div class="relatedtopics">
<xsl:variable name="href"><xsl:value-of select="concat($urlpre,'shared/text/shared/00/00000004.xhp',$urlpost)"/></xsl:variable>
<xsl:variable name="anchor"><xsl:value-of select="'related'"/></xsl:variable>
<xsl:variable name="doc" select="document($href)"/>
<p class="related">
<xsl:apply-templates select="$doc//variable[@id=$anchor]"/>
</p>
<div class="relatedbody">
<xsl:apply-templates />
</div>
</div>
</xsl:when>
<xsl:when test="@id='howtoget'">
<xsl:call-template name="insert_howtoget" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- SECTION -->
<xsl:template match="section" mode="embedded">
<a name="{@id}"></a>
<xsl:apply-templates mode="embedded"/>
</xsl:template>
<!-- SORT -->
<xsl:template match="sort" >
<xsl:apply-templates><xsl:sort select="descendant::paragraph"/></xsl:apply-templates>
</xsl:template>
<xsl:template match="sort" mode="embedded">
<xsl:apply-templates><xsl:sort select="descendant::paragraph"/></xsl:apply-templates>
</xsl:template>
<!-- SWITCH -->
<xsl:template match="switch"><xsl:apply-templates /></xsl:template>
<xsl:template match="switch" mode="embedded"><xsl:apply-templates /></xsl:template>
<!-- SWITCHINLINE -->
<xsl:template match="switchinline"><xsl:apply-templates /></xsl:template>
<xsl:template match="switchinline" mode="embedded"><xsl:apply-templates mode="embedded"/></xsl:template>
<!-- TABLE -->
<xsl:template match="table"><xsl:call-template name="inserttable"/></xsl:template>
<xsl:template match="table" mode="embedded"><xsl:call-template name="inserttable"/></xsl:template>
<!-- TABLECELL -->
<xsl:template match="tablecell"><td valign="top"><xsl:apply-templates /></td></xsl:template>
<xsl:template match="tablecell" mode="icontable"><td valign="top"><xsl:apply-templates/></td></xsl:template>
<xsl:template match="tablecell" mode="embedded"><td valign="top"><xsl:apply-templates mode="embedded"/></td></xsl:template>
<!-- TABLEROW -->
<xsl:template match="tablerow"><tr><xsl:apply-templates /></tr></xsl:template>
<xsl:template match="tablerow" mode="icontable"><tr><xsl:apply-templates mode="icontable"/></tr></xsl:template>
<xsl:template match="tablerow" mode="embedded"><tr><xsl:apply-templates mode="embedded"/></tr></xsl:template>
<!-- TITLE -->
<xsl:template match="title"/>
<!-- TOPIC -->
<xsl:template match="topic"/>
<!-- VARIABLE -->
<xsl:template match="variable"><a name="{@id}"></a><xsl:apply-templates /></xsl:template>
<xsl:template match="variable" mode="embedded"><a name="{@id}"></a><xsl:apply-templates mode="embedded"/></xsl:template>
<xsl:template match="text()">
<xsl:call-template name="brand">
<xsl:with-param name="string"><xsl:value-of select="."/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template match="text()" mode="embedded">
<xsl:call-template name="brand">
<xsl:with-param name="string"><xsl:value-of select="."/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- In case of missing help files -->
<xsl:template match="help-id-missing"><xsl:value-of select="$Id"/></xsl:template>
<!--
###################
# NAMED TEMPLATES #
###################
//-->
<!-- Branding -->
<xsl:template name="brand" >
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains($string,$brand1)">
<xsl:variable name="newstr">
<xsl:value-of select="substring-before($string,$brand1)"/>
<xsl:value-of select="$productname"/>
<xsl:value-of select="substring-after($string,$brand1)"/>
</xsl:variable>
<xsl:call-template name="brand">
<xsl:with-param name="string" select="$newstr"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($string,$brand2)">
<xsl:variable name="newstr">
<xsl:value-of select="substring-before($string,$brand2)"/>
<xsl:value-of select="$pversion"/>
<xsl:value-of select="substring-after($string,$brand2)"/>
</xsl:variable>
<xsl:call-template name="brand">
<xsl:with-param name="string" select="$newstr"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($string,$brand3)">
<xsl:variable name="newstr">
<xsl:value-of select="substring-before($string,$brand3)"/>
<xsl:value-of select="$productname"/>
<xsl:value-of select="substring-after($string,$brand3)"/>
</xsl:variable>
<xsl:call-template name="brand">
<xsl:with-param name="string" select="$newstr"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($string,$brand4)">
<xsl:variable name="newstr">
<xsl:value-of select="substring-before($string,$brand4)"/>
<xsl:value-of select="$pversion"/>
<xsl:value-of select="substring-after($string,$brand4)"/>
</xsl:variable>
<xsl:call-template name="brand">
<xsl:with-param name="string" select="$newstr"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Insert Paragraph -->
<xsl:template name="insertpara">
<xsl:variable name="role">
<xsl:choose>
<xsl:when test="ancestor::table">
<xsl:value-of select="concat(@role,'intable')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@role"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<p class="{$role}"><xsl:apply-templates /></p>
</xsl:template>
<!-- Insert "How to get Link" -->
<xsl:template name="insert_howtoget">
<xsl:param name="linkhref" />
<xsl:variable name="archive" select="'shared'"/>
<xsl:variable name="tmp_href"><xsl:value-of select="concat($urlpre,'shared/text/shared/00/00000004.xhp',$urlpost)"/></xsl:variable>
<xsl:variable name="tmp_doc" select="document($tmp_href)"/>
<table class="howtoget" width="100%" border="1" cellpadding="3" cellspacing="0">
<tr>
<td>
<p class="howtogetheader"><xsl:apply-templates select="$tmp_doc//variable[@id='wie']"/></p>
<div class="howtogetbody">
<xsl:choose>
<xsl:when test="$linkhref = ''"> <!-- new style -->
<xsl:apply-templates/>
</xsl:when>
<xsl:otherwise> <!-- old style -->
<xsl:variable name="archive1"><xsl:value-of select="concat(substring-before(substring-after($linkhref,'text/'),'/'),'/')"/></xsl:variable>
<xsl:variable name="href"><xsl:value-of select="concat($urlpre,$archive1,substring-before($linkhref,'#'),$urlpost)"/></xsl:variable>
<xsl:variable name="anc"><xsl:value-of select="substring-after($linkhref,'#')"/></xsl:variable>
<xsl:variable name="docum" select="document($href)"/>
<xsl:call-template name="insertembed">
<xsl:with-param name="doc" select="$docum" />
<xsl:with-param name="anchor" select="$anc" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</table>
<br/>
</xsl:template>
<!-- Create a link -->
<xsl:template name="createlink">
<xsl:variable name="archive"><xsl:value-of select="concat(substring-before(substring-after(@href,'text/'),'/'),'/')"/></xsl:variable>
<xsl:variable name="dbpostfix"><xsl:call-template name="createDBpostfix"><xsl:with-param name="archive" select="$archive"/></xsl:call-template></xsl:variable>
<xsl:choose>
<xsl:when test="starts-with(@href,'http://') or starts-with(@href,'https://')"> <!-- web links -->
<a href="{@href}"><xsl:apply-templates /></a>
</xsl:when>
<xsl:when test="contains(@href,'#')">
<xsl:variable name="anchor"><xsl:value-of select="concat('#',substring-after(@href,'#'))"/></xsl:variable>
<xsl:variable name="href"><xsl:value-of select="concat($linkprefix,$archive,substring-before(@href,'#'),$linkpostfix,$dbpostfix,$anchor)"/></xsl:variable>
<a href="{$href}"><xsl:apply-templates /></a>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="href"><xsl:value-of select="concat($linkprefix,$archive,@href,$linkpostfix,$dbpostfix)"/></xsl:variable>
<a href="{$href}"><xsl:apply-templates /></a>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Insert Note, Warning, or Tip -->
<xsl:template name="insertnote">
<xsl:param name="type" /> <!-- note, tip, or warning -->
<xsl:variable name="imgsrc">
<xsl:choose>
<xsl:when test="$type='note'"><xsl:value-of select="$note_img"/></xsl:when>
<xsl:when test="$type='tip'"><xsl:value-of select="$tip_img"/></xsl:when>
<xsl:when test="$type='warning'"><xsl:value-of select="$warning_img"/></xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="dbpostfix"><xsl:call-template name="createDBpostfix"><xsl:with-param name="archive" select="'shared'"/></xsl:call-template></xsl:variable>
<xsl:variable name="alt">
<xsl:variable name="href"><xsl:value-of select="concat($urlpre,'shared/',$alttext,$urlpost,$dbpostfix)"/></xsl:variable>
<xsl:variable name="anchor"><xsl:value-of select="concat('alt_',$type)"/></xsl:variable>
<xsl:variable name="doc" select="document($href)"/>
<xsl:apply-templates select="$doc//variable[@id=$anchor]" mode="embedded"/>
</xsl:variable>
<div class="{$type}">
<table border="0" class="{$type}" cellspacing="0" cellpadding="5">
<tr>
<td><img src="{$imgsrc}" alt="{$alt}" title="{$alt}"/></td>
<td><xsl:apply-templates /></td>
</tr>
</table>
</div>
<br/>
</xsl:template>
<!-- Insert a heading -->
<xsl:template name="insertheading">
<xsl:param name="level" />
<xsl:param name="embedded" />
<xsl:text disable-output-escaping="yes">&lt;h</xsl:text><xsl:value-of select="$level"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
<xsl:text disable-output-escaping="yes">&lt;/h</xsl:text><xsl:value-of select="$level"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
</xsl:template>
<!-- Evaluate a case or caseinline switch -->
<xsl:template name="insertcase">
<xsl:param name="embedded" />
<xsl:choose>
<xsl:when test="parent::switch[@select='sys'] or parent::switchinline[@select='sys']">
<xsl:if test="@select = $System">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
<xsl:when test="parent::switch[@select='appl'] or parent::switchinline[@select='appl']">
<xsl:if test="@select = $appl">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
<xsl:when test="parent::switch[@select='distrib'] or parent::switchinline[@select='distrib']">
<xsl:if test="@select = $distrib">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- Evaluate a default or defaultinline switch -->
<xsl:template name="insertdefault">
<xsl:param name="embedded" />
<xsl:choose>
<xsl:when test="parent::switch[@select='sys'] or parent::switchinline[@select='sys']">
<xsl:if test="not(../child::case[@select=$System]) and not(../child::caseinline[@select=$System])">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
<xsl:when test="parent::switch[@select='appl'] or parent::switchinline[@select='appl']">
<xsl:if test="not(../child::case[@select=$appl]) and not(../child::caseinline[@select=$appl])">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
<xsl:when test="parent::switch[@select='distrib'] or parent::switchinline[@select='distrib']">
<xsl:if test="not(../child::case[@select=$distrib]) and not(../child::caseinline[@select=$distrib])">
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- evaluate embeds -->
<xsl:template name="insertembed">
<xsl:param name="doc" />
<xsl:param name="anchor" />
<!-- different embed targets (also falsely used embed instead embedvar) -->
<xsl:choose>
<xsl:when test="$doc//section[@id=$anchor]"> <!-- first test for a section of that name -->
<xsl:apply-templates select="$doc//section[@id=$anchor]" mode="embedded"/>
</xsl:when>
<xsl:when test="$doc//paragraph[@id=$anchor]"> <!-- then test for a para of that name -->
<p class="embedded">
<xsl:apply-templates select="$doc//paragraph[@id=$anchor]" mode="embedded"/>
</p>
</xsl:when>
<xsl:when test="$doc//variable[@id=$anchor]"> <!-- then test for a variable of that name -->
<p class="embedded">
<xsl:apply-templates select="$doc//variable[@id=$anchor]" mode="embedded"/>
</p>
</xsl:when>
<xsl:otherwise> <!-- then give up -->
<p class="bug">D'oh! You found a bug (<xsl:value-of select="@href"/> not found).</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Insert an image -->
<xsl:template name="insertimage">
<xsl:variable name="fpath">
<xsl:call-template name="getfpath">
<xsl:with-param name="s"><xsl:value-of select="@src"/></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fname">
<xsl:call-template name="getfname">
<xsl:with-param name="s"><xsl:value-of select="@src"/></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="src">
<xsl:choose>
<xsl:when test="not($ExtensionId='') and starts-with(@src,$ExtensionId)">
<xsl:value-of select="concat($ExtensionPath,'/',@src)"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="(@localize='true') and not($lang='en-US')">
<xsl:value-of select="concat($img_url_prefix,$fpath,$lang,'/',$fname)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($img_url_prefix,$fpath,$fname)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--<xsl:variable name="src"><xsl:value-of select="concat($img_url_prefix,@src)"/></xsl:variable>-->
<xsl:variable name="alt"><xsl:value-of select="./alt"/></xsl:variable>
<xsl:variable name="width" select="''"/> <!-- Images don't all have the correct size -->
<xsl:variable name="height" select="''"/><!-- Image don't all have the correct size -->
<img src="{$src}" alt="{$alt}" title="{$alt}">
<xsl:if test="not($width='')"><xsl:attribute name="width"><xsl:value-of select="$width"/></xsl:attribute></xsl:if>
<xsl:if test="not($height='')"><xsl:attribute name="height"><xsl:value-of select="$height"/></xsl:attribute></xsl:if>
</img>
</xsl:template>
<!-- Insert a Table -->
<xsl:template name="inserttable">
<xsl:variable name="imgsrc"> <!-- see if we are in an image table -->
<xsl:value-of select="tablerow/tablecell[1]/paragraph[1]/image/@src"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="count(descendant::tablecell)=1">
<table border="0" class="onecell" cellpadding="0" cellspacing="0">
<xsl:apply-templates />
</table>
</xsl:when>
<xsl:when test="descendant::tablecell[1]/descendant::image">
<table border="0" class="icontable" cellpadding="5" cellspacing="0">
<xsl:apply-templates mode="icontable"/>
</table>
</xsl:when>
<xsl:when test="@class='wide'">
<table border="1" class="{@class}" cellpadding="0" cellspacing="0" width="100%" >
<xsl:apply-templates />
</table>
</xsl:when>
<xsl:when test="not(@class='')">
<table border="1" class="{@class}" cellpadding="0" cellspacing="0" >
<xsl:apply-templates />
</table>
</xsl:when>
<xsl:otherwise>
<table border="1" class="border" cellpadding="0" cellspacing="0" >
<xsl:apply-templates />
</table>
</xsl:otherwise>
</xsl:choose>
<br/>
</xsl:template>
<xsl:template name="resolveembed">
<div class="embedded">
<xsl:variable name="archive"><xsl:value-of select="concat(substring-before(substring-after(@href,'text/'),'/'),'/')"/></xsl:variable>
<xsl:variable name="dbpostfix"><xsl:call-template name="createDBpostfix"><xsl:with-param name="archive" select="$archive"/></xsl:call-template></xsl:variable>
<xsl:variable name="href"><xsl:value-of select="concat($urlpre,$archive,substring-before(@href,'#'),$urlpost,$dbpostfix)"/></xsl:variable>
<xsl:variable name="anc"><xsl:value-of select="substring-after(@href,'#')"/></xsl:variable>
<xsl:variable name="docum" select="document($href)"/>
<xsl:call-template name="insertembed">
<xsl:with-param name="doc" select="$docum" />
<xsl:with-param name="anchor" select="$anc" />
</xsl:call-template>
</div>
</xsl:template>
<xsl:template name="resolveembedvar">
<xsl:if test="not(@href='text/shared/00/00000004.xhp#wie')"> <!-- special treatment if howtoget links -->
<xsl:variable name="archive"><xsl:value-of select="concat(substring-before(substring-after(@href,'text/'),'/'),'/')"/></xsl:variable>
<xsl:variable name="dbpostfix"><xsl:call-template name="createDBpostfix"><xsl:with-param name="archive" select="$archive"/></xsl:call-template></xsl:variable>
<xsl:variable name="href"><xsl:value-of select="concat($urlpre,$archive,substring-before(@href,'#'),$urlpost,$dbpostfix)"/></xsl:variable>
<xsl:variable name="anchor"><xsl:value-of select="substring-after(@href,'#')"/></xsl:variable>
<xsl:variable name="doc" select="document($href)"/>
<xsl:choose>
<xsl:when test="$doc//variable[@id=$anchor]"> <!-- test for a variable of that name -->
<xsl:apply-templates select="$doc//variable[@id=$anchor]" mode="embedded"/>
</xsl:when>
<xsl:otherwise> <!-- or give up -->
<span class="bug">[<xsl:value-of select="@href"/> not found].</span>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- Apply -->
<xsl:template name="apply">
<xsl:param name="embedded" />
<xsl:choose>
<xsl:when test="$embedded = 'yes'">
<xsl:apply-templates mode="embedded"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="getfpath">
<xsl:param name="s"/>
<xsl:param name="p"/>
<xsl:choose>
<xsl:when test="contains($s,'/')">
<xsl:call-template name="getfpath">
<xsl:with-param name="p"><xsl:value-of select="concat($p,substring-before($s,'/'),'/')"/></xsl:with-param>
<xsl:with-param name="s"><xsl:value-of select="substring-after($s,'/')"/></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$p"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="getfname">
<xsl:param name="s"/>
<xsl:choose>
<xsl:when test="contains($s,'/')">
<xsl:call-template name="getfname">
<xsl:with-param name="s"><xsl:value-of select="substring-after($s,'/')"/></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$s"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="createDBpostfix">
<xsl:param name="archive"/>
<xsl:variable name="newDB">
<xsl:choose>
<xsl:when test="(substring($archive,1,6) = 'shared')"><xsl:value-of select="$Database"/></xsl:when>
<xsl:otherwise><xsl:value-of select="substring-before($archive,'/')"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($am,'DbPAR=',$newDB)"/>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,94 +0,0 @@
/**************************************************************
*
* 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

@ -1,46 +0,0 @@
<?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

@ -1,114 +0,0 @@
/**************************************************************
*
* 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

@ -1,114 +0,0 @@
/**************************************************************
*
* 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

@ -1,114 +0,0 @@
/**************************************************************
*
* 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

@ -1,114 +0,0 @@
/**************************************************************
*
* 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

@ -1,30 +0,0 @@
###############################################################
#
# 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

File diff suppressed because it is too large Load Diff

View File

@ -1,265 +0,0 @@
<?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>

View File

@ -1,30 +0,0 @@
###############################################################
#
# 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 Calc
Language=zh-CN
Order=3
Start=text%2Fscalc%2Fmain0000.xhp
Heading=headingheading
Program=CALC
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

File diff suppressed because it is too large Load Diff

View File

@ -1,190 +0,0 @@
<?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="scalc" id="08" title="电子表格">
<node id="0801" title="一般信息和用户界面的使用">
<topic id="scalc/text/scalc/main0000.xhp">欢迎使用 %PRODUCTNAME Calc 帮助</topic>
<topic id="scalc/text/scalc/main0503.xhp">%PRODUCTNAME Calc 功能</topic>
<topic id="scalc/text/scalc/guide/keyboard.xhp">快捷键(%PRODUCTNAME Calc 辅助功能)</topic>
<topic id="scalc/text/scalc/04/01020000.xhp">电子表格的快捷键</topic>
<topic id="scalc/text/scalc/05/02140000.xhp">%PRODUCTNAME Calc 中的错误代码</topic>
<topic id="scalc/text/scalc/01/04060112.xhp">%PRODUCTNAME Calc 中用于编程的加载宏</topic>
<topic id="scalc/text/scalc/guide/main.xhp">%PRODUCTNAME Calc 使用说明</topic>
</node>
<node id="0802" title="命令和菜单引用">
<node id="080201" title="菜单">
<topic id="scalc/text/scalc/main0100.xhp">菜单</topic>
<topic id="scalc/text/scalc/main0101.xhp">文件</topic>
<topic id="scalc/text/scalc/main0102.xhp">编辑</topic>
<topic id="scalc/text/scalc/main0103.xhp">视图</topic>
<topic id="scalc/text/scalc/main0104.xhp">插入</topic>
<topic id="scalc/text/scalc/main0105.xhp">格式</topic>
<topic id="scalc/text/scalc/main0106.xhp">工具</topic>
<topic id="scalc/text/scalc/main0107.xhp">窗口</topic>
<topic id="scalc/text/scalc/main0112.xhp">数据</topic>
</node>
<node id="080202" title="工具栏">
<topic id="scalc/text/scalc/main0200.xhp">工具栏</topic>
<topic id="scalc/text/scalc/main0202.xhp">格式栏</topic>
<topic id="scalc/text/scalc/main0203.xhp">绘图对象属性栏</topic>
<topic id="scalc/text/scalc/main0205.xhp">文字格式栏</topic>
<topic id="scalc/text/scalc/main0206.xhp">公式栏</topic>
<topic id="scalc/text/scalc/main0208.xhp">状态栏</topic>
<topic id="scalc/text/scalc/main0210.xhp">打印预览栏</topic>
<topic id="scalc/text/scalc/main0214.xhp">图片栏</topic>
<topic id="scalc/text/scalc/main0218.xhp">工具栏</topic>
<topic id="shared/text/shared/main0201.xhp">标准栏</topic>
<topic id="shared/text/shared/main0209.xhp">超链接地址栏</topic>
<topic id="shared/text/shared/main0212.xhp">表格数据栏</topic>
<topic id="shared/text/shared/main0213.xhp">窗体导航栏</topic>
<topic id="shared/text/shared/main0214.xhp">查询设计栏</topic>
<topic id="shared/text/shared/main0226.xhp">窗体设计工具栏</topic>
</node>
</node>
<node id="0803" title="函数类型和运算符">
<topic id="scalc/text/scalc/01/04060000.xhp">函数向导</topic>
<topic id="scalc/text/scalc/01/04060100.xhp">函数(按类别)</topic>
<topic id="scalc/text/scalc/01/04060101.xhp">数据库函数</topic>
<topic id="scalc/text/scalc/01/04060102.xhp">日期和时间函数</topic>
<topic id="scalc/text/scalc/01/04060103.xhp">财务函数第一部分</topic>
<topic id="scalc/text/scalc/01/04060119.xhp">财务函数第二部分</topic>
<topic id="scalc/text/scalc/01/04060118.xhp">金融函数第三部分</topic>
<topic id="scalc/text/scalc/01/04060104.xhp">信息函数</topic>
<topic id="scalc/text/scalc/01/04060105.xhp">逻辑函数</topic>
<topic id="scalc/text/scalc/01/04060106.xhp">数学函数</topic>
<topic id="scalc/text/scalc/01/04060107.xhp">矩阵函数</topic>
<topic id="scalc/text/scalc/01/04060108.xhp">统计函数</topic>
<topic id="scalc/text/scalc/01/04060181.xhp">统计函数第一部分</topic>
<topic id="scalc/text/scalc/01/04060182.xhp">统计函数第二部分</topic>
<topic id="scalc/text/scalc/01/04060183.xhp">统计函数第三部分</topic>
<topic id="scalc/text/scalc/01/04060184.xhp">统计函数第四部分</topic>
<topic id="scalc/text/scalc/01/04060185.xhp">统计函数第五部分</topic>
<topic id="scalc/text/scalc/01/04060109.xhp">电子表格函数</topic>
<topic id="scalc/text/scalc/01/04060110.xhp">文字函数</topic>
<topic id="scalc/text/scalc/01/04060111.xhp">加载宏函数</topic>
<topic id="scalc/text/scalc/01/04060115.xhp">加载宏函数,分析函数列表第一部分</topic>
<topic id="scalc/text/scalc/01/04060116.xhp">加载宏函数,分析函数列表第二部分</topic>
<topic id="scalc/text/scalc/01/04060199.xhp">%PRODUCTNAME Calc 中的运算符</topic>
<topic id="scalc/text/scalc/guide/userdefined_function.xhp">自定义函数</topic>
</node>
<node id="0804" title="加载、保存、导入和导出">
<topic id="scalc/text/scalc/guide/webquery.xhp">在表格中插入外部数据 (WebQuery)</topic>
<topic id="scalc/text/scalc/guide/html_doc.xhp">将工作表以 HTML 格式保存和打开</topic>
<topic id="scalc/text/scalc/guide/csv_formula.xhp">导入和导出文本文件</topic>
</node>
<node id="0805" title="格式化">
<topic id="scalc/text/scalc/guide/text_rotate.xhp">旋转文字</topic>
<topic id="scalc/text/scalc/guide/text_wrap.xhp">写入多行文字</topic>
<topic id="scalc/text/scalc/guide/text_numbers.xhp">将数字格式化为文本</topic>
<topic id="scalc/text/scalc/guide/super_subscript.xhp">文字上标/下标</topic>
<topic id="scalc/text/scalc/guide/row_height.xhp">改变行高或列宽</topic>
<topic id="scalc/text/scalc/guide/cellstyle_conditional.xhp">应用条件格式</topic>
<topic id="scalc/text/scalc/guide/cellstyle_minusvalue.xhp">突出显示负数</topic>
<topic id="scalc/text/scalc/guide/cellstyle_by_formula.xhp">根据公式指定的格式</topic>
<topic id="scalc/text/scalc/guide/integer_leading_zero.xhp">输入带前置零的数字</topic>
<topic id="scalc/text/scalc/guide/format_table.xhp">格式化电子表格</topic>
<topic id="scalc/text/scalc/guide/format_value.xhp">格式化带小数的数字</topic>
<topic id="scalc/text/scalc/guide/value_with_name.xhp">命名单元格</topic>
<topic id="scalc/text/scalc/guide/table_rotate.xhp">旋转表格(转置)</topic>
<topic id="scalc/text/scalc/guide/rename_table.xhp">重命名工作表</topic>
<topic id="scalc/text/scalc/guide/year2000.xhp">19xx/20xx 年</topic>
<topic id="scalc/text/scalc/guide/rounding_numbers.xhp">使用四舍五入的数字</topic>
<topic id="scalc/text/scalc/guide/currency_format.xhp">采用货币格式的单元格</topic>
<topic id="scalc/text/scalc/guide/autoformat.xhp">对表格使用自动套用格式</topic>
<topic id="scalc/text/scalc/guide/note_insert.xhp">插入和编辑批注</topic>
<topic id="scalc/text/scalc/guide/design.xhp">选择工作表主题</topic>
<topic id="scalc/text/scalc/guide/fraction_enter.xhp">输入分数</topic>
</node>
<node id="0806" title="筛选和排序">
<topic id="scalc/text/scalc/guide/filters.xhp">应用筛选</topic>
<topic id="scalc/text/scalc/guide/specialfilter.xhp">筛选:应用高级筛选</topic>
<!-- removed scalc/text/scalc/guide/standardfilter.xhp -->
<topic id="scalc/text/scalc/guide/autofilter.xhp">应用自动筛选</topic>
<topic id="scalc/text/scalc/guide/sorted_list.xhp">应用排序列表</topic>
</node>
<node id="0807" title="打印">
<topic id="scalc/text/scalc/guide/print_title_row.xhp">在每一页上打印行或列</topic>
<topic id="scalc/text/scalc/guide/print_landscape.xhp">横向打印工作表</topic>
<topic id="scalc/text/scalc/guide/print_details.xhp">打印工作表详细资料</topic>
<topic id="scalc/text/scalc/guide/print_exact.xhp">定义打印的页数</topic>
</node>
<node id="0808" title="数据区域">
<topic id="scalc/text/scalc/guide/database_define.xhp">定义数据库区域</topic>
<topic id="scalc/text/scalc/guide/database_filter.xhp">过滤单元格范围</topic>
<!-- removed scalc/text/scalc/guide/database_group.xhp -->
<topic id="scalc/text/scalc/guide/database_sort.xhp">数据排序 </topic>
</node>
<node id="0809" title="数据透视表">
<topic id="scalc/text/scalc/guide/datapilot.xhp">数据透视表</topic>
<topic id="scalc/text/scalc/guide/datapilot_createtable.xhp">创建数据透视表</topic>
<topic id="scalc/text/scalc/guide/datapilot_deletetable.xhp">删除数据透视表</topic>
<topic id="scalc/text/scalc/guide/datapilot_edittable.xhp">编辑数据透视表</topic>
<topic id="scalc/text/scalc/guide/datapilot_filtertable.xhp">筛选数据透视表</topic>
<topic id="scalc/text/scalc/guide/datapilot_tipps.xhp">选择数据透视表输出范围</topic>
<topic id="scalc/text/scalc/guide/datapilot_updatetable.xhp">更新数据透视表</topic>
</node>
<node id="0810" title="方案">
<topic id="scalc/text/scalc/guide/scenario.xhp">使用方案</topic>
</node>
<node id="0811" title="引用">
<topic id="scalc/text/scalc/guide/relativ_absolut_ref.xhp">地址和引用,绝对和相对</topic>
<topic id="scalc/text/scalc/guide/cellreferences.xhp">引用其他文档中的单元格</topic>
<topic id="scalc/text/scalc/guide/cellreferences_url.xhp">引用其他工作表和参考 URL</topic>
<topic id="scalc/text/scalc/guide/cellreference_dragdrop.xhp">通过拖放来引用单元格</topic>
<topic id="scalc/text/scalc/guide/address_auto.xhp">寻址时识别名称</topic>
</node>
<node id="0812" title="查看、选择和复制">
<topic id="scalc/text/scalc/guide/table_view.xhp">修改表格视图</topic>
<topic id="scalc/text/scalc/guide/formula_value.xhp">显示公式或数值</topic>
<topic id="scalc/text/scalc/guide/line_fix.xhp">行或列作为标题固定</topic>
<topic id="scalc/text/scalc/guide/multi_tables.xhp">浏览工作表标签</topic>
<topic id="scalc/text/scalc/guide/edit_multitables.xhp">复制到多个工作表</topic>
<topic id="scalc/text/scalc/guide/cellcopy.xhp">仅复制可见单元格</topic>
<topic id="scalc/text/scalc/guide/mark_cells.xhp">选择多个单元格</topic>
</node>
<node id="0813" title="公式和计算">
<topic id="scalc/text/scalc/guide/formulas.xhp">通过公式计算</topic>
<topic id="scalc/text/scalc/guide/formula_copy.xhp">复制公式</topic>
<topic id="scalc/text/scalc/guide/formula_enter.xhp">输入公式</topic>
<topic id="scalc/text/scalc/guide/formula_value.xhp">显示公式或数值</topic>
<topic id="scalc/text/scalc/guide/calculate.xhp">电子表格中的计算</topic>
<topic id="scalc/text/scalc/guide/calc_date.xhp">使用日期和时间进行计算</topic>
<topic id="scalc/text/scalc/guide/calc_series.xhp">自动计算序列</topic>
<topic id="scalc/text/scalc/guide/calc_timevalues.xhp">计算时差</topic>
<topic id="scalc/text/scalc/guide/matrixformula.xhp">输入矩阵公式</topic>
</node>
<node id="0814" title="保护">
<topic id="scalc/text/scalc/guide/cell_protect.xhp">保护单元格不被修改</topic>
<topic id="scalc/text/scalc/guide/cell_unprotect.xhp">取消单元格保护</topic>
</node>
<node id="0815" title="其他">
<!-- removed scalc/text/scalc/guide/autofill.xhp -->
<topic id="scalc/text/scalc/guide/auto_off.xhp">停用自动修改</topic>
<topic id="scalc/text/scalc/guide/consolidate.xhp">合并计算数据</topic>
<topic id="scalc/text/scalc/guide/goalseek.xhp">应用单变量求解</topic>
<topic id="scalc/text/scalc/guide/multioperation.xhp">应用多重计算</topic>
<topic id="scalc/text/scalc/guide/multitables.xhp">应用多个工作表</topic>
<topic id="scalc/text/scalc/guide/validity.xhp">单元格内容的有效性</topic>
</node>
</help_section>
</tree_view>

View File

@ -1,30 +0,0 @@
###############################################################
#
# 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 Chart
Language=zh-CN
Order=4
Start=text%2Fschart%2Fmain0000.xhp
Heading=headingheading
Program=CHART
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

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
<?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="scalc" id="05" title="图表和图解">
<node id="0501" title="一般信息">
<topic id="schart/text/schart/main0000.xhp">%PRODUCTNAME 中的图表</topic>
<topic id="schart/text/schart/main0503.xhp">%PRODUCTNAME 图表功能</topic>
<topic id="schart/text/schart/04/01020000.xhp">图表的快捷键</topic>
</node>
</help_section>
</tree_view>

View File

@ -1,30 +0,0 @@
###############################################################
#
# 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 Base
Language=zh-CN
Order=7
Start=text%2Fshared%2Fexplorer%2Fdatabase%2Fmain.xhp
Heading=headingheading
Program=DATABASE
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

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